将数组从 Julia 发送到 Rust使用“ccall” 朱莉娅方面锈面

问题描述

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

我有 Julia 代码:

A = Array{Float64,1}(undef,2)
print("A is ",A,"\n")
ccall((:recvstruct,"target/debug/liblib"),Float64,(Ref{Array{Float64,1}},Int32,),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.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000693291100915563,0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069329110091572,0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Julia 已安装:Version 1.5.2 锈(货物):cargo 1.49.0 (d00d64df9 2020-12-05)

解决方法

朱莉娅方面

(argtype1,...)ccall 中,将 recvstruct 的第一个参数的类型声明为指向带有 Ptr{T} 的内存地址的指针。

直接来自 ccall docs

通过自动插入对 unsafe_convert(argtype,cconvert(argtype,argvalue)) 的调用,ccall 的每个 argvalue 将转换为相应的 argtype

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

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 被标记为不安全。手册页的安全部分包含所有需要考虑的细节。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...