Julia与Rust的相互作用
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"
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。但是你应该使用它,因为它更容易。