朱莉娅与鲁斯特之间的互动

时间:2018-08-19 10:50:47

标签: rust julia

Julia和Rust之间是否有任何互动的方式,允许以下方式:

  1. 从Julia调用/执行Rust函数
  2. 从Rust调用/执行Julia

谢谢

2 个答案:

答案 0 :(得分:6)

  

从Julia调用Rust函数,例如ccall

alexcrichton/rust-ffi-examples回购中有一个示例:

Cargo.toml

[package]
name = "julia-to-rust"
version = "0.1.0"
authors = ["timmonfette1 <monfette.timothy@gmail.com>"]

[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

这个想法是,您导出一个无损函数,并将rust库编译为普通的本机共享库。然后,您只需使用Julia的标准C FFI。

  

从Rust致电Julia

我想为此使用julia crate更好-它为raw C API提供了一个安全的包装器。回购示例:

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
}

答案 1 :(得分:2)

从Rust中执行Julia

使用Rust的Command

创建一个包含以下内容的main.jl文件:

# __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")

创建一个包含以下内容的main.rs文件:

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);
        }
    }
}

然后,通过运行cargo run,您将在下面获得所需的输出:

enter image description here

从Julia中执行Rust

使用calling-c-and-fortran-codeccall

使用包含以下内容的lib.rs文件创建Rust共享库:

#[no_mangle]
pub extern fn double_input(input: i32) -> i32 {
    println!("Hello from Rust");
    input * 2
}

用于构建库的Cargo.toml

[package]
name = "julia_call_rust"
version = "1.0.0"
authors = ["hasan yousef]

[lib]
name = "my_rust_lib"
crate-type = ["dylib"]

创建一个main.jl文件,其中包含:

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")

运行cargo build来构建Rust库,然后运行julia main.jl来获取下面的所需输出:

enter image description here