【发布时间】:2020-02-02 11:40:04
【问题描述】:
我有一个外部库(例如 libcisland.so),其界面如下:
size_t lib_handle_size();
typedef void* handle;
int lib_init(handle h);
int lib_store(handle h, int value);
int lib_restore(handle h, int *pvalue);
这个库的用户应该做以下事情:
// allocate some buffer in client address space
handle h = malloc(lib_handle_size());
// pass this buffer to library for initialization
if (lib_init(h)) { /* handle errors */ }
// library initializes this handle by some opaque fashion
// then user uses it
lib_store(h,42);
int r;
lib_restore(h,&r);
// after all work is done, user frees this handle
free(h);
我不知道如何正确地将这个接口包装到 Rust。 这就是我最终的结果:
pub struct Island {
h: Handle,
v: Vec<u8>,
}
impl Island {
pub fn new() -> Island {
let len = unsafe { lib_handle_size() };
let mut v: Vec<u8> = Vec::with_capacity(len);
let h: Handle = v.as_mut_ptr();
Island { v:v, h:h, }
}
pub fn store(&mut self, v: i32) {
unsafe { lib_store(self.h, v); }
}
pub fn restore(&mut self) -> i32 {
let mut v = 0;
unsafe { lib_restore(self.h, &mut v); }
v
}
}
impl Drop for Island {
fn drop(&mut self) {
drop(&mut self.v);
}
}
/// unsafe part
use libc::size_t;
pub type Handle = *mut u8;
#[link(name="cisland")]
extern {
pub fn lib_handle_size() -> size_t;
pub fn lib_init(h: Handle) -> i32;
pub fn lib_store(h: Handle, value: i32) -> i32;
pub fn lib_restore(h: Handle, pvalue: &mut i32) -> i32;
}
可以为此目的使用Vec(u8) 吗?这个Drop trait 实现了吗?
【问题讨论】:
-
drop(&mut self.v);创建对v的引用,然后删除该引用,什么也不做。 Drops 会自动递归调用,除非你需要做一些特殊的事情,否则你不需要写任何东西。