将Python列表传递给Rust函数

pen*_*123 5 python ffi rust

我有一个Rust库需要通过ctypes模块导入到Python中.我的目标是使用带有Vec<T>/ i32作为参数的Rust函数并从Python返回这些类型.目前,我可以将整数传递给Rust函数,并让它们返回列表/整数.这是当前的代码:

蟒蛇:

import ctypes
from ctypes import cdll

class List_4(ctypes.Structure):
    _fields_ = [("array", ctypes.ARRAY(ctypes.c_int32, 4))]

rust = cdll.LoadLibrary("target/debug/py_link.dll")
rust.function_vec.restype = List_4

foobar = rust.function_i32(5)
barbaz = rust.function_vec([1, 2, 3, 4]) # Throws error: Don't know how to convert parameter

print foobar
print barbaz
Run Code Online (Sandbox Code Playgroud)

锈:

#[repr(C)]
pub struct List_4 {
    array: [i32; 4]
}

#[no_mangle]
pub extern fn function_i32(number: i32) -> i32 {
    number
}

#[no_mangle]
pub extern fn function_vec(list: List_4) -> List_4 {
    List_4 { array: [1, 2, 3, 5] }
}
Run Code Online (Sandbox Code Playgroud)

我需要帮助的是将Python列表作为参数传递给Rust函数.我最好的猜测是ctypes.ARRAY将函数传递给函数而不是列表,但我不确定如何将Python列表转换为该类型.

注意:我尝试了相关问题的Rust代码,但是当我尝试编译它时,它说"与`gcc`链接失败:退出代码:1"和"错误的重定位地址".

pen*_*123 4

看来我解决了这个问题。我将 Python 列表转换为 C 数组,并将其传递给 Rust 函数。这是工作代码:

#[repr(C)]
pub struct List_4 {
    // Create a struct using #[repr(C)], will do the same in Python so it is shareable
    array: [i32; 4]
}

#[no_mangle]
pub extern fn function_array(list: List_4) -> List_4 {
    // Return a new instance of List_4
    List_4 { array: [1, 2, 3, 5] }
}
Run Code Online (Sandbox Code Playgroud)

Python:

import ctypes # By using ctypes, and #[repr(C)], we use the same type
              # of data in both languages, so it is possible to send stuff between them

rust = cdll.LoadLibrary("target/debug/py_link.dll") # Import the Rust dll

class List_4(ctypes.Structure):
    # Similar to creating the struct in Rust
    _fields_ = [("array", ctypes.ARRAY(ctypes.c_int32, 4))]

rust.function_array.restype = List_4 # Set the function's return type to List_4

def function_array(arr):
    # For convenience, a function to convert a list to a C array, call the function,
    # and convert its return value to a list
    return list(
        rust.function_array(
            (ctypes.c_int * len(lst))(*lst) # Call the function after converting the list 
        ).array
    )

# To use the function:
>>> function_array([1, 2, 3])
[1, 2, 3, 5]
Run Code Online (Sandbox Code Playgroud)