Is it valid to use ptr::NonNull in FFI?

半城伤御伤魂 提交于 2019-12-10 18:40:11

问题


Rust has the ptr::NonNull type that represents a non-NULL pointer. Is it safe to use this type in FFI?

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));

with

extern "C" fn call_me_from_c(without_nulls: ptr::NonNull<c_char>)

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.


回答1:


It depends on what version of Rust you are compiling with.

Rust 1.29 and up

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>,
}

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):

Structs with this representation have the same layout and ABI as the single non-zero sized field.

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.



来源:https://stackoverflow.com/questions/49392712/is-it-valid-to-use-ptrnonnull-in-ffi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!