是否有通用的Rust指针类型可以存储任何其他类型的指针,类似于C的void *?

use*_*932 1 pointers rust

我想为我的板条箱创建一个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 *),因为那样就不可能拥有存储位置的真实地址。

She*_*ter 5

没有。

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 ++标准声明可以强制转换为它。

并非总是如此: