gpt4 book ai didi

rust - 如何将 Rust `Vec` 暴露给 FFI?

转载 作者:行者123 更新时间:2023-11-29 07:41:59 25 4
gpt4 key购买 nike

我正在尝试构造一对元素:

  • 数组:*mut T
  • array_len: 使用大小

array 旨在拥有数据

然而,Box::into_raw将返回 *mut [T]。我找不到任何关于将原始指针转换为切片的信息。它在内存中的布局是什么?我如何从 C 中使用它?我应该转换为 *mut T 吗?如果是,怎么办?

最佳答案

如果你只是想让一些 C 函数可变地借用 Vec,你可以这样做:

extern "C" {
fn some_c_function(ptr: *mut i32, len: ffi::size_t);
}

fn safe_wrapper(a: &mut [i32]) {
unsafe {
some_c_function(a.as_mut_ptr(), a.len() as ffi::size_t);
}
}

当然,C 函数不应该将此指针存储在其他地方,因为那样会破坏别名假设。

如果您想将数据的所有权“传递”给 C 代码,您可以这样做:

use std::mem;

extern "C" {
fn c_sink(ptr: *mut i32, len: ffi::size_t);
}

fn sink_wrapper(mut vec: Vec<i32>) {
vec.shrink_to_fit();
assert!(vec.len() == vec.capacity());
let ptr = vec.as_mut_ptr();
let len = vec.len();
mem::forget(vec); // prevent deallocation in Rust
// The array is still there but no Rust object
// feels responsible. We only have ptr/len now
// to reach it.
unsafe {
c_sink(ptr, len as ffi::size_t);
}
}

在这里,C 函数“取得所有权”是指我们期望它最终将指针和长度返回给 Rust,例如,通过调用 Rust 函数来释放它:

#[no_mangle]
/// This is intended for the C code to call for deallocating the
/// Rust-allocated i32 array.
unsafe extern "C" fn deallocate_rust_buffer(ptr: *mut i32, len: ffi::size_t) {
let len = len as usize;
drop(Vec::from_raw_parts(ptr, len, len));
}

因为 Vec::from_raw_parts 需要三个参数,一个指针,一个大小和一个容量,我们要么必须以某种方式跟踪容量,要么我们使用 Vec 的 shr​​ink_to_fit 在将指针和长度传递给 C 函数之前。不过,这可能涉及重新分配。

关于rust - 如何将 Rust `Vec<T>` 暴露给 FFI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39224904/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com