在FFI中使用ptr :: NonNull是否有效? [英] Is it valid to use ptr::NonNull in FFI?
问题描述
Rust具有 ptr::NonNull
类型表示非NULL
指针.在FFI中使用这种类型是否安全?
Rust has the ptr::NonNull
type that represents a non-NULL
pointer. Is it safe to use this type in FFI?
是否保证具有相同的二进制表示形式(忽略非FFI上下文,例如Option
优化),对齐方式,将使用情况注册为*mut T
?
Is it guaranteed to have same binary representation (ignoring non-FFI context such as Option
optimizations), alignment, register usage as *mut T
?
例如,我可以实现此接口吗?
For example, could I implement this 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
争论.
I don't expect this to do anything (apart from causing UB when misused with NULL
;), but I would like the interface to document that the function requires non-NULL
arguments.
推荐答案
这取决于您使用的Rust版本.
It depends on what version of Rust you are compiling with.
NonNull
现在具有repr(transparent)
,因此只要包装类型是安全的,就可以在FFI中安全使用.
NonNull
now has repr(transparent)
, so it is safe to use in FFI so long as the wrapped type is safe.
#[stable(feature = "nonnull", since = "1.25.0")]
#[repr(transparent)]
pub struct NonNull<T: ?Sized> {
pointer: NonZero<*const T>,
}
在Rust 1.29之前
我不会不将其用于此类用途.主要原因是由于其定义:
Before Rust 1.29
I would not use it for such. The main reason is due to its definition:
#[stable(feature = "nonnull", since = "1.25.0")]
pub struct NonNull<T: ?Sized> {
pointer: NonZero<*const T>,
}
More specifically, I'm concerned about what's not in the definition: #[repr(transparent)]
(emphasis mine):
具有这种表示形式的结构具有相同的布局和ABI 作为单个非零大小的字段.
Structs with this representation have the same layout and ABI as the single non-zero sized field.
由于将新类型放在FFI函数中,我经历了错误编译,因此repr(transparent)
不只是学术练习.
I've experienced miscompilation due to putting newtypes in a FFI function that were solved by repr(transparent)
, so this isn't just an academic exercise.
这篇关于在FFI中使用ptr :: NonNull是否有效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!