我一直在摆弄这个使用看似简单的Box函数,试图创建一些FFI辅助代码。
这里的示例似乎在与具有字段的结构体一起使用时会报错:free(): invalid pointer
。
pub struct Handle(usize);
impl Handle {
pub fn from<T>(obj: T) -> Self {
let boxed = Box::new(obj);
let mut ptr = Box::into_raw(boxed);
Self::from_ptr_mut(&mut ptr)
}
pub fn from_ptr_mut<T>(ptr: &mut T) -> Self {
Self(ptr as *mut T as usize)
}
pub fn to_box<T>(self) -> Box<T> {
let obj: *mut T = self.to_ptr_mut();
unsafe { Box::from_raw(obj) }
}
pub fn to_ptr_mut<T>(self) -> *mut T {
self.0 as *mut T
}
}
#[allow(dead_code)]
struct Crashes { value: u64 }
impl Drop for Crashes {
fn drop(&mut self) {
println!("Crashes dropped");
}
}
fn crashes() {
let t = Crashes { value: 12 };
let a = Handle::from(t);
let b = a.to_box::<Crashes>();
drop(b);
}
struct Works;
impl Drop for Works {
fn drop(&mut self) {
println!("Works dropped");
}
}
fn works() {
let t = Works;
let a = Handle::from(t);
let b = a.to_box::<Works>();
drop(b);
}
fn main() {
works();
crashes();
}
你可以将此代码粘贴到https://play.rust-lang.org/中,看它如何抛出错误
free(): invalid pointer
。看起来,drop函数在适当的时间被调用,但指针似乎有些无效。