在asking之后我应该如何在FFI边界上释放内存,Rust reddit上的某个人建议我可以使用Entity
而不是将我的结构包装在Box
中。从以下结构构造一个向量,并且可以安全地删除它:
Vec::from_raw_parts
但是,#[repr(C)]
pub struct Array {
data: *const c_void,
len: libc::size_t,
}
似乎需要from_raw_parts
数据,因此我不确定如何继续...
答案 0 :(得分:9)
答案非常简短self.data as *mut u8
。但是,让我们谈谈更多细节......
首先,警告的话:
不使用Vec::from_raw_parts
,除非指针最初来自Vec
。 无保证任意指针与Vec
兼容,如果继续,您可能会在程序中创建巨大漏洞。
不释放您不拥有的指针。这样做会导致双重释放,这将会破坏程序中的其他大洞。
您需要了解向量的容量,然后才能重新构建它。您的示例结构只包含len
。只有len
和capacity
相等时,才能接受此项。
现在,让我们看看我是否可以遵循自己的规则......
extern crate libc;
use std::mem;
#[repr(C)]
pub struct Array {
data: *const libc::c_void,
len: libc::size_t,
}
// Note that both of these methods should probably be implementations
// of the `From` trait to allow them to participate in more places.
impl Array {
fn from_vec(mut v: Vec<u8>) -> Array {
v.shrink_to_fit(); // ensure capacity == size
let a = Array {
data: v.as_ptr() as *const libc::c_void,
len: v.len(),
};
mem::forget(v);
a
}
fn into_vec(self) -> Vec<u8> {
unsafe { Vec::from_raw_parts(self.data as *mut u8, self.len, self.len) }
}
}
fn main() {
let v = vec![1, 2, 3];
let a = Array::from_vec(v);
let v = a.into_vec();
println!("{:?}", v);
}
请注意,我们不必明确删除Vec
,因为Drop
的正常Vec
实现正在发挥作用。我们必须确保正确构建Vec
。