Julia与Rust的相互作用

Julia与Rust的相互作用,rust,julia,Rust,Julia,Julia和Rust之间是否有互动的方式,允许: 从Julia调用/执行Rust函数 从Rust调用/执行Julia 谢谢 从Julia调用Rust函数,比如ccall 回购协议中有一个例子: Cargo.toml: [package] name = "julia-to-rust" version = "0.1.0" authors = ["timmonfette1 <monfette.timothy@gmail.com>"] [lib] name = "double_input"

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

  • 从Julia调用/执行Rust函数
  • 从Rust调用/执行Julia
  • 谢谢

    从Julia调用Rust函数,比如ccall

    回购协议中有一个例子:

    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/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库编译为一个普通的本机共享库。然后你只需要使用朱莉娅的标准C FFI

    从Rust打电话给Julia

    我想最好使用它,它提供了一个安全的包装。回购协议的例子:

    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
    }
    
    把茱莉亚从锈迹中除掉 使用铁锈

    创建包含以下内容的
    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")
    
    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);
            }
        }
    }
    
    #[no_mangle]
    pub extern fn double_input(input: i32) -> i32 {
        println!("Hello from Rust");
        input * 2
    }
    
    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")
    
    创建包含以下内容的
    main.rs
    文件:

    # __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")
    
    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);
            }
        }
    }
    
    #[no_mangle]
    pub extern fn double_input(input: i32) -> i32 {
        println!("Hello from Rust");
        input * 2
    }
    
    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 run
    ,您将获得以下所需输出:

    从茱莉亚那里除锈 使用

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

    # __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")
    
    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);
            }
        }
    }
    
    #[no_mangle]
    pub extern fn double_input(input: i32) -> i32 {
        println!("Hello from Rust");
        input * 2
    }
    
    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.toml

    [package]
    name = "julia_call_rust"
    version = "1.0.0"
    authors = ["hasan yousef]
    
    [lib]
    name = "my_rust_lib"
    crate-type = ["dylib"]
    
    创建一个
    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")
    
    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);
            }
        }
    }
    
    #[no_mangle]
    pub extern fn double_input(input: i32) -> i32 {
        println!("Hello from Rust");
        input * 2
    }
    
    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
    以生成锈迹库,并运行
    julia main.jl
    以获得以下所需输出:


    检查这个问题是否很漂亮,如果是相反的方式,也就是从Rust给Julia打电话呢?@ozkriff,我想你可以把这个问题扩展成一个答案!如何使输出文件如
    run.o
    而不是make文件?@HasanAYousef如何将rust代码编译到静态库?应该会有帮助你不用用julia板条箱。你可以自己运行bindgen。但是你应该使用它,因为它更容易。