在FFI中使用ptr :: NonNull是否有效?

时间:2018-03-20 19:32:13

标签: rust ffi abi non-nullable

Rust具有代表非NULL指针的ptr::NonNull类型。在FFI中使用这种类型是否安全?

是否保证具有相同的二进制表示(忽略非FFI上下文,如Option优化),对齐,寄存器使用为*mut T

例如,我可以实现此接口:

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),但我希望接口记录该函数需要非{ {1}}参数。

1 个答案:

答案 0 :(得分:1)

这取决于您正在编译的Rust版本。

Rust 1.29及以上

NonNull 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)](强调我的):

  

具有此表示的结构具有与单个非零大小字段相同的相同布局和ABI

由于repr(transparent) {{1}}解决了putting newtypes in a FFI function导致的错误编译,所以这不仅仅是一次学术活动。