pga*_*kst 6 c ffi ownership rust
我正在调用一个 C 构造函数keyNew
,该函数为结构分配内存Key
并将 a 返回*mut Key
到 Rust 端。使用Box::from_raw
包装指针并获取它的所有权是否合适?
我也可以直接返回原始指针,但这会导致 API 非常丑陋,而且对于 Rust 来说并不符合习惯。
我还想在 Key 上实现 Drop Trait,以便keyDel
自动调用析构函数,这将是对 C 中手动调用的改进。在我看来,这是一个更好的 API。然而,实现 Drop Trait 要求不实现 Copy Trait,因此由于“移出取消引用的内容”,不再可能取消引用原始指针。
他们的密钥是由 rust-bindgen 生成的
#[repr(C)]
#[derive(Debug, Clone)]
pub struct Key {
_unused: [u8; 0],
}
Run Code Online (Sandbox Code Playgroud)
的构造函数Key
是这样实现的
fn new() -> Box<Key> {
unsafe { Box::from_raw(keyNew(0 as *const i8)) }
}
Run Code Online (Sandbox Code Playgroud)
和析构函数
impl Drop for Key {
fn drop(&mut self) {
unsafe { keyDel(self) };
}
}
Run Code Online (Sandbox Code Playgroud)
这一切都运行得非常好,我可以使用Box<Key
像 aKey
这样的 Deref,并且当超出 scpekeyDel
时会自动调用。Box<Key
但是我不确定这是否合适,因为 Rust 文档有这样的说法Box::from_raw
调用此函数后,原始指针归结果 Box 所有。具体来说,Box 析构函数将调用 T 的析构函数并释放分配的内存。由于 Box 分配和释放内存的方式未指定,因此传递给该函数的唯一有效指针是通过 Box::into_raw 函数从另一个 Box 获取的指针。
我稍后不会打电话Box::into_raw
,所以这一切在记忆方面仍然有效吗?如果没有,有什么替代方法可以获取返回的所有权*mut Key
?
使用 Box::from_raw 包装指针并获取它的所有权是否合适?
文档为from_raw
您解答:
由于 Box 分配和释放内存的方式未指定,因此传递给该函数的唯一有效指针是通过该函数从另一个 Box 获取的
Box::into_raw
指针。
这意味着您当前的使用情况未指定。
我还想在Key上实现Drop Trait,以便自动调用析构函数keyDel
你不应该实现Drop
forKey
因为Key
它不是由 Rust 分配的。理想情况下,您可以创建自己的包装类型,使用自己的drop 来调用keyDel
指针。例如:
struct KeyWrapper {
ptr: NonNull<Key>
}
impl Drop for KeyWrapper {
fn drop(&mut self) {
keyDel(self.ptr.as_ptr())
}
}
impl KeyWrapper {
fn new() {
KeyWrapper {
ptr: NonNull::new(keyNew(0 as *const i8))
}
}
fn someUtil(&self) {
// As an example, you could call through to some C function.
keySomeUtil(self.ptr.as_ptr())
}
}
Run Code Online (Sandbox Code Playgroud)
这样,在 Rust 方面,您只与包装指针的类型进行交互,并且keyDel
当指针被删除时它将调用。您的工作是确保此包装器类型仅通过 C API 执行安全操作,以免使 Rust 的安全保证失效。
有关的: