我有这个C代码:
typedef void (*f_t)(int a);
struct Foo {
f_t f;
};
extern void f(struct Foo *);
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)>,
}
我不明白为什么Option
在这里。显然Rust enum
和C指针在位级别上是不一样的,所以Rust编译器如何处理它?</ p>
当我调用C f
函数并将指针传递给Rust结构Foo
时,编译器是否将Foo_rust
转换为Foo_C
,然后仅传递指针Foo_C
到f
?
答案 0 :(得分:5)
来自The Rust Programming Language chapter on FFI(强调我的):
某些类型被定义为不为null。这包括引用(
&T
,&mut T
),框(Box<T>
)和函数指针(extern "abi" fn()
)。当与C接口时,经常使用可能为null的指针。作为一种特殊情况,包含两个变体的通用枚举,其中一个不包含数据,另一个包含单个字段,有资格进行&#34;可空指针优化&#34;。当用非可空类型之一实例化这样的枚举时,它被表示为单个指针,并且非数据变量被表示为空指针。 所以Option<extern "C" fn(c_int) -> c_int>
是使用C ABI表示可空函数指针的方式。
另一种说法:
显然,Rust枚举和C指针在位级上不是一回事
当Option
包含一组特定类型时,它们实际上是。
另见: