使用Drop trait释放repr(C)结构的正确习惯用法

使用Drop trait释放repr(C)结构的正确习惯用法,c,memory,rust,C,Memory,Rust,这段代码工作正常,但在Rust nightly(1.2)上给出编译器警告 它链接到C库并正确创建/删除单元格对象。然而,它给出了一个警告 src\lib.rs:27:1: 33:2 warning: implementing Drop adds hidden state to types, possibly conflicting with `#[repr(C)]`, #[warn(drop_with_repr_extern)] on by default \src\lib.rs:27 impl

这段代码工作正常,但在Rust nightly(1.2)上给出编译器警告

它链接到C库并正确创建/删除单元格对象。然而,它给出了一个警告

src\lib.rs:27:1: 33:2 warning: implementing Drop adds hidden state to types, possibly conflicting with `#[repr(C)]`, #[warn(drop_with_repr_extern)] on by default
\src\lib.rs:27 impl Drop for DbaxCell {
\src\lib.rs:28     fn drop(&mut self) {
\src\lib.rs:29         unsafe {
\src\lib.rs:30             deleteCell(self.cell);
\src\lib.rs:31         }
\src\lib.rs:32     }

正确的方法是什么,以确保正确清理这些
DbaxCell
s,并且不发出警告?

我认为您混淆了两个概念。如果希望结构的布局与结构的布局直接对应,则结构应该是
repr(C)
。也就是说,它具有相同的内存
repr
esention

但是,如果您只是持有一个原始指针,并且不打算将持有结构传递回C,则不需要这样做。在这种情况下,简短的解决方案是“remove
repr(C)

要进一步解释有关错误的信息

实现Drop会将隐藏状态添加到类型中,可能与
#[repr(C)]

这一点在会议上进行了讨论。删除对象时,将设置一个隐藏标志(“状态”),指示对象已删除,以防止发生多次删除。但是,隐藏位意味着您在Rust中看到的内容与C中的结构字节不一致,从而否定了
repr(C)
的用途

作为:


低级程序员,不用担心:将完全删除此删除标志

使用
repr(C)
在FFI中传递结构,如果需要,在“常规锈蚀”结构上使用
Drop
。如果两者都需要,请将
repr(C)
结构嵌入到常规结构中

假设我们有一个库,它公开了一个包含两个8位数字的C结构,以及获取并返回该结构的方法:

typedef struct {
    char a;
    char b;
} tuple_t;

tuple_t tuple_increment(tuple_t position);
在这种情况下,您肯定希望模拟该结构并匹配Rust中的C表示:

#[repr(C)]
struct Tuple {
    a: libc::char,
    b: libc::char,
}
但是,如果库返回指向结构的指针,并且您永远不需要插入它(结构是不透明的),那么您就不必担心
repr(C)

然后您可以使用该指针并实现Drop:

struct TuplePointer(*mut libc::c_void);

impl Drop for TuplePointer {
    // Call the appropriate free function from the library
}

低级程序员,别担心:未来的锈迹会完全清除掉这个掉旗。。最近的进展比表面上看起来的要多。我希望这将是今年的某个时候。也许这个答案应该解释得更多一些?使用
repr(C)
在ffi中传递结构,如果需要,在“常规锈蚀”结构上使用
Drop
。如果两者都需要,请将
repr(C)
struct嵌入常规的rust结构中。@bluss介意给我上一次更新看一看并提供一些反馈吗?
void tuple_increment(tuple_t *position);
struct TuplePointer(*mut libc::c_void);

impl Drop for TuplePointer {
    // Call the appropriate free function from the library
}