Is there any way to interact between Julia and Rust, a way that allow:
Thanks
Calling Rust function from Julia, like ccall
There's an example for this in alexcrichton/rust-ffi-examples repo:
Cargo.toml
:
[package]
name = "julia-to-rust"
version = "0.1.0"
authors = ["timmonfette1 <[email protected]>"]
[lib]
name = "double_input"
crate-type = ["dylib"]
src/lib.rs
:
#[no_mangle]
pub extern fn double_input(input: i32) -> i32 {
input * 2
}
src/main.jl
:
input = Int32(10)
output = ccall((:double_input, "target/debug/libdouble_input"),
Int32, (Int32,), input)
print(input)
print(" * 2 = ")
println(output)
Makefile
:
ifeq ($(shell uname),Darwin)
EXT := dylib
else
EXT := so
endif
all: target/debug/libdouble_input.$(EXT)
julia src/main.jl
target/debug/libdouble_input.$(EXT): src/lib.rs Cargo.toml
cargo build
clean:
rm -rf target
The idea is that you export a non-mangled function and compile your rust library to a normal native shared library. Then you just use standard C FFI of Julia.
Calling Julia from Rust
I guess it's better to use julia
crate for this - it provides a safe wrapper over a raw C API. Example from the repo:
fn main() {
use julia::api::{Julia, Value};
let mut jl = Julia::new().unwrap();
jl.eval_string("println(\"Hello, Julia!\")").unwrap();
// Hello, Julia!
let sqrt = jl.base().function("sqrt").unwrap();
let boxed_x = Value::from(1337.0);
let boxed_sqrt_x = sqrt.call1(&boxed_x).unwrap();
let sqrt_x = f64::try_from(boxed_sqrt_x).unwrap();
println!("{}", sqrt_x);
// 36.565010597564445
}
Use Rust's Command
.
Create a main.jl
file that contains:
# __precompile__() # If required to be kept precompiled for faster execution
# name = isempty(ARGS) ? "name" : ARGS[1] # To check input arguments
println("hello from Julia function")
Create a main.rs
file that contains:
use std::process::Command;
fn main() {
println!("Hello from Rust");
let mut cmd = Command::new("Julia");
cmd.arg("main.jl");
// cmd.args(&["main.jl", "arg1", "arg2"]);
match cmd.output() {
Ok(o) => unsafe {
println!("Output: {}", String::from_utf8_unchecked(o.stdout));
},
Err(e) => {
println!("There was an error {}", e);
}
}
}
Then, by running cargo run
you'll get the required output below:
Use the calling-c-and-fortran-code by ccall
Create a Rust shared library using a lib.rs
file that contains:
#[no_mangle]
pub extern fn double_input(input: i32) -> i32 {
println!("Hello from Rust");
input * 2
}
The Cargo.toml
for building the library:
[package]
name = "julia_call_rust"
version = "1.0.0"
authors = ["hasan yousef]
[lib]
name = "my_rust_lib"
crate-type = ["dylib"]
Create a main.jl
file, that contains:
println("Hello from Julia")
input = 10 #Int32(10)
output = ccall( #(:function or "function", "library"), Return type, (Input types,), arguments if any)
(:double_input,
"target/debug/libmy_rust_lib"),
Int32, # Return type
(Int32,), # (Input types,)
input) # Arguments if any
println("As result of $input * 2 is: $output")
Run cargo build
to get the Rust library built, and run julia main.jl
to get the required output below:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With