将 Rust 与 C API 和 mut/pointer 类型问题结合使用

Using Rust with C API and mut/pointer problems with types

我正在尝试使用 Rust 与低级 C API 交互。它需要调用以获取数组的大小,然后使用分配的结构数组再次调用以匹配该大小,函数看起来像

getVals(pNumItems: *mut usize,
        pItems: *mut)

根据 API 用法,我这样做:

let mut numItems: usize = 0;
getVals(&numItems,
        ptr::null_mut());

// Now we know count, so make an array of MyInfo structs and call again:

let itemInfo: Vec<MyInfo> = Vec::with_capacity(numItems);
getVals(&numItems, itemInfo.as_mut_ptr());

但是第一次调用无法编译,因为我收到错误消息:

mismatched types expected raw pointer *mut u32 found reference &usize let mut items

我不清楚这里有什么区别。我尝试将其转换为 *mut u32 但抱怨它不安全。这整段代码都是在里面完成的

unsafe{}

所以,我想我做的不正确。有更好的方法吗?

我的向量创建和使用没有编译时错误,但我不确定这是否是预期的方式?

你可能想做这样的事情。

#[repr(C)]
struct MyInfo {
    a: i32,
    b: f32,
}

extern "C" {
    fn getVals(
        pNumItems: *mut usize,
        pItems: *mut MyInfo,
    );
}

fn main() {
    // first detect required size
    let mut num_items: usize = 0;
    unsafe { getVals(&mut num_items, std::ptr::null_mut()) };

    // then allocate storage and get items
    let mut item_info: Vec<MyInfo> = Vec::with_capacity(num_items);
    unsafe { getVals(&mut num_items, item_info.as_mut_ptr()) };
    unsafe { item_info.set_len(num_items) };
}

#[repr(C)] 注释确保结构的布局与 C 兼容。

你的函数必须声明为extern "C":它的定义不是由 Rust 提供的,并且没有对符号名称应用任何修饰。

调用这样的 extern 函数时,需要一个 unsafe 块(因为 Rust 编译器无法保证此调用的安全性)。

为了获得指向 num_items*mut 指针,您需要从 &mut 引用开始(而不是 &,后者只能提供 *const指针)。

调用将数据存储到分配的缓冲区后,您需要调整向量的长度,因为它不知道您对其分配的存储空间做了什么(当然这是不安全的;您是唯一的)知道这是正确的)。

如果编译器抱怨 *mut u32&usize,那可能是因为您在 getVals() 中声明了 pNumItems: *mut u32。 如果你真的想要这个(因为在 C 端 uint32_t 是预期的),那么你需要在调用站点声明 let mut num_items: u32 = 0; 并使用 Vec::with_capacity(num_items as usize).set_len(num_items as usize).