这段代码工作正常,但每晚都会在Rust上发出编译器警告(1.2)
#[repr(C)]
struct DbaxCell {
cell: *const c_void
}
#[link(name="CDbax", kind="dylib")]
extern {
fn new_dCell(d: c_double) -> *const c_void;
fn deleteCell(c: *const c_void);
}
impl DbaxCell {
fn new(x: f64) -> DbaxCell {
unsafe {
DbaxCell { cell: new_dCell(x) }
}
}
}
impl Drop for DbaxCell {
fn drop(&mut self) {
unsafe {
deleteCell(self.cell);
}
}
}
它链接到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)
如果你希望结构的布局 直接对应 作为C编译器将结构布局。也就是说,它具有相同的内存 repr
esentation。
但是,你 别 需要的是,如果你只是持有一个原始指针,并且不会将保持结构传递回C.在这种情况下的简短解决方案是“删除 repr(C)
”。
更多地解释错误......
实现Drop会向类型添加隐藏状态,可能与之冲突 #[repr(C)]
这是在讨论中 问题24585。删除对象时,会设置隐藏标志(“状态”),表示该对象已被删除,从而防止发生多次丢弃。但是,隐藏位意味着您在Rust中看到的内容与C中结构的字节不一致,从而否定了 repr(C)
。
如 来自@bluss:
低级程序员,不要担心: 未来的锈 将完全删除此删除标记。
和
使用 repr(C)
在FFI中传递结构,并使用 Drop
如果你需要,可以使用“常规Rust”结构。如果你需要两者,嵌入 repr(C)
常规结构中的struct。
想象一下,我们有一个库,它公开了一个带有两个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)
:
void tuple_increment(tuple_t *position);
然后你可以使用该指针并实现Drop:
struct TuplePointer(*mut libc::c_void);
impl Drop for TuplePointer {
// Call the appropriate free function from the library
}
我认为你正在混淆两个概念。结构应该是 repr(C)
如果你希望结构的布局 直接对应 作为C编译器将结构布局。也就是说,它具有相同的内存 repr
esentation。
但是,你 别 需要的是,如果你只是持有一个原始指针,并且不会将保持结构传递回C.在这种情况下的简短解决方案是“删除 repr(C)
”。
更多地解释错误......
实现Drop会向类型添加隐藏状态,可能与之冲突 #[repr(C)]
这是在讨论中 问题24585。删除对象时,会设置隐藏标志(“状态”),表示该对象已被删除,从而防止发生多次丢弃。但是,隐藏位意味着您在Rust中看到的内容与C中结构的字节不一致,从而否定了 repr(C)
。
如 来自@bluss:
低级程序员,不要担心: 未来的锈 将完全删除此删除标记。
和
使用 repr(C)
在FFI中传递结构,并使用 Drop
如果你需要,可以使用“常规Rust”结构。如果你需要两者,嵌入 repr(C)
常规结构中的struct。
想象一下,我们有一个库,它公开了一个带有两个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)
:
void tuple_increment(tuple_t *position);
然后你可以使用该指针并实现Drop:
struct TuplePointer(*mut libc::c_void);
impl Drop for TuplePointer {
// Call the appropriate free function from the library
}