将数组从 Julia 发送到 Rust(使用 "ccall")

Send array from Julia to Rust (using "ccall")

谁能解释一下?如何使用“ccall”函数将任何数组从 julia 发送到 rust。发送usial变量或者常量都没有问题

我有 Julia 代码:

A = Array{Float64,1}(undef, 2)
print("A is ",A, "\n")
ccall((:recvstruct, "target/debug/liblib"),Float64, (Ref{Array{Float64,1}}, Int32,), A, sizeof(A))

Rust代码

#[no_mangle]
pub extern fn recvstruct(vec: &mut Vec<f64> , len: usize){
    println!("reiceved?: {:?}", len);
    println!("reiceved?: {:?}", vec);
}

输出为:

A is [0.0, 0.0]
Hello from cargo

reiceved?: 16

和奇怪的无尽数组:

, 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069329110091509, 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000693291559949425, 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000693291100915405, 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000693291559949425, 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000693291100915405, 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000693291559949425, 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000693291100915563, 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000693291559949425, 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000693291100915563, 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000693291559949425, 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000693291100915563, 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000693291559949425, 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069329110091572, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

朱莉娅已安装:Version 1.5.2 铁锈(货物):cargo 1.49.0 (d00d64df9 2020-12-05)

朱莉娅这边

ccall(argtype1, ...) 中,将 recvstruct 的第一个参数的类型声明为指向具有 Ptr{T}.

的内存地址的指针

直接来自 ccall docs:

Each argvalue to the ccall will be converted to the corresponding argtype, by automatic insertion of calls to unsafe_convert(argtype, cconvert(argtype, argvalue))

传递数组元素的数量而不是数组的字节大小:

a = [2.0, 3.0]
result = ccall((:recvstruct, "target/debug/liblib"), Float64, (Ptr{Float64}, UInt,), a, length(a))
println("got: $result")

锈面

recvstruct 的第一个参数声明为指向 float64 数组的内存指针。

此外,使用 slice::from_raw_parts 获取值切片。

例如:

#[no_mangle]
pub extern "C" fn recvstruct(array_ptr: *const f64, len: usize) -> f64 {
    _recvstruct(unsafe {
        std::slice::from_raw_parts(array_ptr as *const f64, len)
    }, len)
}

fn _recvstruct(vec: &[f64] , len: usize) -> f64 {
    match len {
        2 => vec[0] * vec[1],
        _ => 0.0
    }
}

请注意,from_raw_parts 被标记为不安全。手册页的安全部分包含所有需要考虑的细节。