Rust 有 ptr::NonNull
表示非 NULL
指针的类型。在 FFI 中使用这种类型安全吗?
是否保证与 *mut T
具有相同的二进制表示(忽略非 FFI 上下文,例如 Option
优化)、对齐、寄存器使用?
例如,我可以实现这个接口(interface)吗:
void call_me_from_c(char *without_nulls) __attribute__((nonnull));
与
extern "C" fn call_me_from_c(without_nulls: ptr::NonNull<c_char>)
我不希望它做任何事情(除了在误用 NULL
时导致 UB 之外),但我希望界面记录该函数需要非NULL
参数。
最佳答案
这取决于您编译时使用的 Rust 版本。
Rust 1.29 及更高版本
非空
now has repr(transparent)
, 所以只要包装类型是安全的,就可以安全地在 FFI 中使用。
#[stable(feature = "nonnull", since = "1.25.0")]
#[repr(transparent)]
pub struct NonNull<T: ?Sized> {
pointer: NonZero<*const T>,
}
Rust 1.29 之前
我不会将它用于此类目的。主要原因是由于its definition :
#[stable(feature = "nonnull", since = "1.25.0")]
pub struct NonNull<T: ?Sized> {
pointer: NonZero<*const T>,
}
更具体地说,我关心定义中不的内容:#[repr(transparent)]
(强调我的):
Structs with this representation have the same layout and ABI as the single non-zero sized field.
由于 putting newtypes in a FFI function,我遇到了编译错误repr(transparent)
解决了这个问题,所以这不仅仅是一个学术练习。
关于rust - 在 FFI 中使用 ptr::NonNull 是否有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49392712/