Pass a C array to a Rust function

2019-01-20 12:24发布

问题:

I'm trying to make a Rust dylib and use it from other languages, like C, Python and others. I've successfully called a Rust function taking and i32 argument from python. Now I'm trying to make a function, that takes an array (pointer to it, or whatever necessary to pass a dataset to Rust lib).

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

This works as expected. But

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

fails with

src/lib.rs:5:2: 6:2 error: type `i32` cannot be dereferenced
src/lib.rs:5    *(arrayPointer + 1)
src/lib.rs:6 }

Also this:

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

and doing something like array[0] fails with "length = 0" error.

回答1:

You have to make some efforts to provide pure C api and implement some conversions using unsafe code. Fortunately, it is not so difficult:

extern crate libc;

#[no_mangle]
pub extern 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]
}

There is a good introduction for rust FFI on the official site.



回答2:

Just want to point out that in @swizard's code he's getting unsigned ints and converting them to signed ints. The code you probably want is

extern crate libc;

#[no_mangle]

pub extern 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]
}


标签: c arrays rust