repr(C)类型如何处理Option?

use*_*932 2 rust

我有这个C代码:

typedef void (*f_t)(int a);

struct Foo {
        f_t f;
};

extern void f(struct Foo *);
Run Code Online (Sandbox Code Playgroud)

bindgen生成以下Rust代码(我删除了不重要的细节):

#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct Foo {
    pub f: ::std::option::Option<extern "C" fn(a: ::std::os::raw::c_int)>,
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么Option在这里.显然Rust enum和C指针在位级别上是不一样的,所以Rust编译器如何处理这个?

当我调用C f函数并将指针传递给Rust结构时Foo,编译器是否转换Foo_rustFoo_C然后仅将指针传递Foo_Cf

She*_*ter 5

来自关于FFI的Rust编程语言章节(强调我的):

某些类型被定义为不为null.这包括引用(&T,&mut T),方框(Box<T>)和函数指针(extern "abi" fn()).当与C接口时,经常使用可能为null的指针.作为一种特殊情况,包含两个变体的通用枚举,其中一个不包含数据,另一个包含单个字段,符合"可空指针优化"的条件.当用非可空类型之一实例化这样的枚举时,它被表示为单个指针,并且非数据变量被表示为空指针.那么Option<extern "C" fn(c_int) -> c_int>如何使用C ABI表示可空函数指针.

换句话说:

显然,Rust枚举和C指针在位级别上并不相同

实际上,它们Option包含一组特定的类型.


也可以看看: