如何拥有生锈的C指针并适当地将其丢弃?

如何拥有生锈的C指针并适当地将其丢弃?,c,rust,ffi,ownership,C,Rust,Ffi,Ownership,我正在调用一个C构造函数keyNew,它为Keystruct分配内存,并将*mut Key返回到strust端。使用Box::from_raw包装指针并获取其所有权是否合适 我也可以直接返回原始指针,但这会导致非常难看的API,而且不适合生锈 我还想在键上实现Drop特性,这样可以自动调用析构函数keyDel,这将是对C中手动调用的改进。我认为这是一个更好的API。但是,实现Drop特性需要不实现Copy特性,因此由于“移出已解除引用的内容”,无法再解除对原始指针的引用 它们的密钥是由rust

我正在调用一个C构造函数
keyNew
,它为
Key
struct分配内存,并将
*mut Key
返回到strust端。使用
Box::from_raw
包装指针并获取其所有权是否合适

我也可以直接返回原始指针,但这会导致非常难看的API,而且不适合生锈

我还想在键上实现Drop特性,这样可以自动调用析构函数
keyDel
,这将是对C中手动调用的改进。我认为这是一个更好的API。但是,实现Drop特性需要不实现Copy特性,因此由于“移出已解除引用的内容”,无法再解除对原始指针的引用

它们的密钥是由rust bindgen生成的

#[repr(C)]
#[派生(调试、克隆)]
发布结构键{
_未使用:[u8;0],
}
键的构造函数是这样实现的

fn new()->框{
不安全{Box::from_raw(keyNew(0为*const i8))}
}
还有析构函数

impl下拉键{
fn下降(&mut自我){
不安全{keyDel(self)};
}
}
这一切都非常好,我可以使用
框
使用Box::from_raw包装指针并获得其所有权是否合适

答案如下:

由于未指定Box分配和释放内存的方式,因此传递到此函数的唯一有效指针是通过
Box::into_raw
函数从另一个Box获取的指针

这意味着您当前的使用情况未指定

我还想在键上实现Drop特性,以便自动调用析构函数keyDel

您不应该为
执行
拖放
,因为
不是由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())
  }
}
struct-KeyWrapper{
ptr:NonNull
}
密钥包装器的impl Drop{
fn下降(&mut自我){
keyDel(self.ptr.as_ptr())
}
}
impl密钥包装器{
fn新的(){
钥匙套{
ptr:NonNull::new(keyNew(0作为常量i8))
}
}
fn someUtil(&self){
//例如,您可以调用某些C函数。
keySomeUtil(self.ptr.as_ptr())
}
}
这样,在Rust端,您只与封装指针的类型进行交互,当指针被丢弃时,它将调用
keyDel
。您的工作是确保此包装类型仅通过C API执行安全操作,以免使Rust的安全保证失效

相关的: