如何从Python读取返回的Rust dll指针

2024-10-02 14:29:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我想将f64向量从Rust返回到Python,但我不确定如何在Python端取消引用返回的指针

lib.rs

use libc::c_double;

#[no_mangle]
pub extern "C" fn give_me_array() -> *const Vec<c_double> {

    let array_to_pass = vec![1.05, 1.07, 2.48];    // Just an example... there are some calculations here

    &array_to_pass

}

请求_array.py

from cffi import FFI
ffi = FFI()
ffi.cdef("""
    double* give_me_array();
""")

dll = ffi.dlopen("...path_to_dll...")
returned_array = dll.give_me_array()
print(returned_array)

输出是一个内存位置:

<cdata 'double *' 0x00000....>

预期产出: 1.05,1.07,2.48

如何在python端取消对数组的引用? 这是将可变大小的向量从Rust传递到Python的最佳方法吗

Aiden4提供的生锈端解决方案和Python端的修改

lib.rs

use libc; // 0.2.93

#[repr(C)]
pub struct CDoubleArray {
    pub ptr: *mut libc::c_double,
    pub len: usize,
}
#[no_mangle]
pub extern "C" fn give_me_array() -> CDoubleArray {
    let vec = vec![1.05, 1.07, 2.48];
    let len = vec.len();
    CDoubleArray {
        ptr: vec.leak().as_mut_ptr(), //leaked so the caller is responsible for the memory
        len,
    }
}
#[no_mangle]
pub unsafe extern "C" fn free_array(arr: CDoubleArray) {
    // since the caller is responsible for the memory we have to provide a way to free it
    Vec::from_raw_parts(arr.ptr, arr.len, arr.len);
}

请求_array.py

from cffi import FFI
ffi = FFI()
ffi.cdef("""

    typedef struct {
        double *v2_ptr;
        unsigned long v2_size;
    } CDoubleArray;

    CDoubleArray give_me_array();
    void free_array(CDoubleArray);
    
""")

dll = ffi.dlopen("...path_to.dll...")
returned_array = ffi.new("CDoubleArray *")
returned_array = dll.give_me_array()

for n in range(returned_array.v2_size):
    print(returned_array.v2_ptr[n])

Tags: thetolenarraymedlldoublepub