将 C 数组传递给 Rust 函数

Pass a C array to a Rust function

我正在尝试制作一个 Rust dylib 并在其他语言中使用它,例如 C、Python 和其他语言。我已经成功地调用了一个 Rust 函数,它从 Python 中获取一个 i32 参数。现在我正在尝试创建一个函数,它接受一个数组(或一个指向它的指针,或者将数据集传递给 Rust 所需的任何东西)。

#![crate_type = "dylib"]
#[no_mangle]
pub extern "C" fn rust_multiply(size: i32, arrayPointer: &i32) -> i32 {
    *(arrayPointer)
}

这按预期工作。但是

#![crate_type = "dylib"]
#[no_mangle]
pub extern "C" fn rust_multiply(size: i32, arrayPointer: &i32) -> i32 {
    *(arrayPointer + 1) // trying to get next element
}

失败

error[E0614]: type `i32` cannot be dereferenced
 --> src/lib.rs:4:5
  |
4 |     *(arrayPointer + 1) // trying to get next element
  |     ^^^^^^^^^^^^^^^^^^^

这样做:

pub extern fn rust_multiply(size: i32, array: &[i32]) -> i32

并且执行类似 array[0] 的操作失败并出现“长度 = 0”错误。

您必须做出一些努力来提供纯 C API 并使用不安全代码实现一些转换。幸运的是,它并没有那么难:

extern crate libc;

#[no_mangle]
pub extern "C" fn rust_multiply(
    size: libc::size_t,
    array_pointer: *const libc::uint32_t,
) -> libc::uint32_t {
    internal_rust_multiply(unsafe {
        std::slice::from_raw_parts(array_pointer as *const i32, size as usize)
    }) as libc::uint32_t
}

fn internal_rust_multiply(array: &[i32]) -> i32 {
    assert!(!array.is_empty());
    array[0]
}

Rust FFI 有很好的介绍on the official site

获取无符号整数并将它们转换为有符号整数。您可能需要的代码是

extern crate libc;

#[no_mangle]

pub extern "C" fn rust_multiply(
    size: libc::size_t,
    array_pointer: *const libc::int32_t,
) -> libc::int32_t {
    internal_rust_multiply(unsafe {
        std::slice::from_raw_parts(array_pointer as *const i32, size as usize)
    }) as libc::int32_t
}

fn internal_rust_multiply(array: &[i32]) -> i32 {
    assert!(!array.is_empty());
    array[0]
}