FFI:将可空指针转换为选项
FFI: Convert nullable pointer to option
我正在使用 rust-bindgen 从 Rust 访问 C 库。某些函数 return 指向结构的可空指针,bindgen 表示为
extern "C" {
pub fn get_some_data() -> *const SomeStruct;
}
现在,对于更高级别的包装器,我想将其转换为具有适当生命周期的 Option<&'a SomeStruct>
。由于可空指针优化,这实际上与 *const SomeStruct
相同。但是,我找不到在两者之间转换的任何简洁语法。转化
let data: Option<&'a SomeStruct> = unsafe { mem::transmute( get_some_data() ) };
再借
let data_ptr = get_some_data();
let data = if data_ptr.is_null() { None } else { unsafe { &*data_ptr } };
可以使用。 mem::transmute
的 docs 表示
transmute is incredibly unsafe. There are a vast number of ways to cause undefined behavior with this function. transmute should be the absolute last resort.
并建议重新借入
Turning a *mut T into an &mut T
但是,对于可空指针,如第二个示例所示,这非常笨拙。
问:这个转换有更简洁的语法吗?或者,有没有办法告诉 bindgen 生成
extern "C" {
pub fn get_some_data() -> Option<&SomeStruct>;
}
直接?
使用 <*const T>::as_ref
¹:
let data = unsafe { get_some_data().as_ref() };
由于原始指针可能无法指向任何 'a
具有足够生命周期的有效对象,as_ref
是 unsafe
调用。
*mut T
有对应的as_mut
→Option<&mut T>
.
¹ 这与 as_ref
不同,例如 AsRef::as_ref
and Option::as_ref
,两者在安全代码中都很常见。
我正在使用 rust-bindgen 从 Rust 访问 C 库。某些函数 return 指向结构的可空指针,bindgen 表示为
extern "C" {
pub fn get_some_data() -> *const SomeStruct;
}
现在,对于更高级别的包装器,我想将其转换为具有适当生命周期的 Option<&'a SomeStruct>
。由于可空指针优化,这实际上与 *const SomeStruct
相同。但是,我找不到在两者之间转换的任何简洁语法。转化
let data: Option<&'a SomeStruct> = unsafe { mem::transmute( get_some_data() ) };
再借
let data_ptr = get_some_data();
let data = if data_ptr.is_null() { None } else { unsafe { &*data_ptr } };
可以使用。 mem::transmute
的 docs 表示
transmute is incredibly unsafe. There are a vast number of ways to cause undefined behavior with this function. transmute should be the absolute last resort.
并建议重新借入
Turning a *mut T into an &mut T
但是,对于可空指针,如第二个示例所示,这非常笨拙。
问:这个转换有更简洁的语法吗?或者,有没有办法告诉 bindgen 生成
extern "C" {
pub fn get_some_data() -> Option<&SomeStruct>;
}
直接?
使用 <*const T>::as_ref
¹:
let data = unsafe { get_some_data().as_ref() };
由于原始指针可能无法指向任何 'a
具有足够生命周期的有效对象,as_ref
是 unsafe
调用。
*mut T
有对应的as_mut
→Option<&mut T>
.
¹ 这与 as_ref
不同,例如 AsRef::as_ref
and Option::as_ref
,两者在安全代码中都很常见。