Rust中不透明外部静态的最合适类型?

3htmauhk  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(125)

我想获得一个指向FFI定义的static的原始指针,* 它的具体类型对Rust* 是不透明的。
这是我目前拥有的:

use std::{ffi::c_void, ptr::addr_of};

fn ptr_to_foo() -> *const c_void {
    extern "C" {
        static FOO: /* what type here? */;
    }

    unsafe { addr_of!(FOO).cast() }
}

但是FOO应该用什么类型声明呢?
如果内存位置的字节可能对该类型无效,那么声明它c_void是否是UB--即使我只创建了指向该位置的原始指针,而从未构造引用(或者更糟的是,解引用指针/阅读内存)?
如果是这样的话,有没有比u8更合适的方法,或者这(或者围绕它的新类型)是推荐的方法?

3lxsmp7m

3lxsmp7m1#

如果你在夜间使用extern types,它们是一个只在夜间使用的方法,用来创建一个动态大小的类型,编译器知道它在任何情况下都不能解引用,并且是专门为ffi设计的。

#![feature(extern_types)]
extern "C"{
    type Foo;
    static FOO: Foo;
}

Playground
另一个选择是使用大小为零的类型,该类型具有私有字段,但没有公共构造函数:

#[repr(C)]
struct Foo{
    _inner: [u8;0]
}

extern "C"{
    static FOO: Foo;
}

Playground
如果你使用的指针是非空的,对齐良好的,并且没有指向释放的内存,那么ZST读写总是有效的,所以虽然你仍然可以从静态中读取,但是这样做是定义良好的。唯一需要注意的是,如果返回的指针有别名,那么将指针转换为可变引用将导致未定义的行为,但是这是静态的问题,而不是类型的问题。

相关问题