铁锈具有ptr::NonNull https://doc.rust-lang.org/beta/std/ptr/struct.NonNull.html代表非的类型NULL
指针。在 FFI 中使用这种类型安全吗?
是否保证具有相同的二进制表示形式(忽略非 FFI 上下文,例如Option
优化),对齐,寄存器使用为*mut T
?
例如,我可以实现这个接口吗:
void call_me_from_c(char *without_nulls) __attribute__((nonnull));
with
extern "C" fn call_me_from_c(without_nulls: ptr::NonNull<c_char>)
我不希望这do任何事情(除了误用时导致UBNULL
;),但我希望接口能够记录该函数需要非NULL
论据。
这取决于您使用哪个版本的 Rust 进行编译。
Rust 1.29 及更高版本
NonNull
now has repr(transparent) https://github.com/rust-lang/rust/blob/1.29.0/src/libcore/ptr.rs#L2846-L2850,所以只要包装型是安全的,在FFI中使用就是安全的。
#[stable(feature = "nonnull", since = "1.25.0")]
#[repr(transparent)]
pub struct NonNull<T: ?Sized> {
pointer: NonZero<*const T>,
}
Rust 1.29 之前
I would not用它来做这样的事。主要原因是由于它的定义 https://github.com/rust-lang/rust/blob/1.28.0/src/libcore/ptr.rs#L2842-L2845:
#[stable(feature = "nonnull", since = "1.25.0")]
pub struct NonNull<T: ?Sized> {
pointer: NonZero<*const T>,
}
更具体地说,我关心的是not在定义中:#[repr(transparent)] https://doc.rust-lang.org/stable/reference/type-layout.html#the-transparent-representation(强调我的):
具有这种表示形式的结构具有相同的布局和 ABI作为单个非零大小的字段。
我经历过编译错误,因为将新类型放入 FFI 函数中 https://stackoverflow.com/a/49020435/155423已解决repr(transparent)
,所以这不仅仅是一个学术练习。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)