我想为我的板条箱创建一个C FFI API,但尚不清楚强制转换指针的安全性。伪代码:
#[no_mangle]
extern "C" fn f(...) -> *mut c_void {
let t: Box<T> = ...;
let p = Box::into_raw(t);
p as *mut c_void
}
Run Code Online (Sandbox Code Playgroud)
这可以按预期工作,但它的安全性如何?在C或C ++中,有一个特殊的void *指针,并且C ++标准声明可以强制转换为它。潜在地,sizeof(void *)可以是不相等的sizeof(T *),但有一个保证sizeof(void *)> = sizeof(T *)。
那Rust呢?是否有关于std::mem::size_of指针的保证或指针之间的安全转换?还是所有指针的实现大小相等,等于usize?
“通用”是指您可以转换X *而不会丢失任何东西。我不在乎类型信息;我关心的是指向不同事物的指针的大小不同,例如16位天中的near/ far指针。
4.10说
将“ pointer to cv T”转换为“ pointer to cv void”的结果指向类型为T的对象所在的存储位置的起点,
,这是不可能的sizeof(void *) < sizeof(T *),因为那样就不可能拥有存储位置的真实地址。
没有。
Rust的原始指针(和引用)目前有两种形式:
use std::mem;
fn main() {
println!("{}", mem::size_of::<*const u8>()); // 8
println!("{}", mem::size_of::<*const [u8]>()); // 16
}
Run Code Online (Sandbox Code Playgroud)
没有可以同时存储两者的类型。即使是“大锤子” mem::transmute也无法使用:
use std::mem;
unsafe fn example(mut thin: *const u8, mut fat: *const [u8]) {
fat = mem::transmute(thin);
thin = mem::transmute(fat);
}
Run Code Online (Sandbox Code Playgroud)
use std::mem;
fn main() {
println!("{}", mem::size_of::<*const u8>()); // 8
println!("{}", mem::size_of::<*const [u8]>()); // 16
}
Run Code Online (Sandbox Code Playgroud)
由于胖指针的布局是Rust特定的概念,因此绝不应通过FFI访问它们。这意味着仅应使用细指针,所有细指针均具有统一的已知大小。
也可以看看:
在C或C ++中,有一个特殊的
void *指针,并且C ++标准声明可以强制转换为它。
并非总是如此:
| 归档时间: |
|
| 查看次数: |
130 次 |
| 最近记录: |