我是Rust的新手,并选择了一个超越我的项目。
我有一个现有的C库,我想为它提供Rust绑定。库的基本数据结构是一个节点,它可以有许多子节点,零个或一个父节点。
在我的sys
库中,我代表我从C lib中获取的不透明指针
pub enum NodeRef {}
此外,我有这些FFI声明
extern {
pub fn NodeNew() -> *mut NodeRef;
pub fn NodeInsertChild(node: *mut NodeRef, child: *mut NodeRef, index: uint32_t);
pub fn NodeGetParent(node: *const NodeRef) -> *mut NodeRef;
pub fn NodeFree(node: *mut NodeRef);
}
现在到了困难的部分。我想将它们包装在一个安全的界面中。
#[derive(Debug, PartialEq, Eq)]
pub struct Node {
reference: *mut ffi::NodeRef,
__parent: Option<???>,
}
impl Drop for Node {
fn drop(&mut self) {
unsafe { ffi::NodeFree(self.reference) }
}
}
impl Node {
pub fn new() -> Self {
let node = unsafe { ffi::NodeNew() };
assert!(!node.is_null());
Node {
reference: node,
__parent: None
}
}
pub fn push_front(&mut self, node: &mut Node) {
unsafe { ffi::NodeInsertChild(self.reference, node.reference, 0) }
node.__parent = Some(???);
}
pub fn parent(&self) -> Option<???> {
self.__parent
}
}
我想表示添加子节点和检索节点父节点的操作。但是,我不确定如何正确指定对象的生命周期。我认为我需要自己保留父母的引用,以便推断它的生命周期,因为返回ffi::NodeGetParent
会导致节点双重释放。