Edd*_*ett 11 boolean ffi type-conversion rust
一位同事和我一直在讨论如何通过FFI bool从<stdbool.h>(又名_Bool)返回Rust.
我们想要在Rust中使用我们的C99代码:
bool
myfunc(void) {
...
}
Run Code Online (Sandbox Code Playgroud)
我们让Rust了解myfunc使用extern C块:
extern "C" {
fn myfunc() -> T;
}
Run Code Online (Sandbox Code Playgroud)
具体类型应该T是什么?
锈没有c_bool在libc箱子的,如果你在网上搜索,你会发现各种GitHub的问题和RFC中,人们讨论这个问题,但真的不来,什么是正确和便携式任何共识:
据我所知:
这一评论表明,如果一个C99 bool被传递给函数的参数或出功能的返回值,并在bool比C的情况下int则提升到相同大小作为int.在这种情况下,我们可以告诉Rust T是u32.
好吧,但如果(由于某种原因)C99 bool是64位宽怎么办?是否u32还安全吗?也许在这种情况下,我们会截断4个最重要的字节,这很好,因为4个最低有效字节足以表示true和false.
我的推理是否正确?在Rust得到之前libc::c_bool,你将使用什么?T为什么它对于所有可能尺寸的C99 bool(> = 1位)都是安全和便携的?
截至2018年2月1日,Rust的bool大小正式与C的_Bool大小相同.
这意味着这bool是在FFI中使用的正确类型.
在做出正式决定之前,本答案的其余部分适用于Rust的版本
在Rust得到之前
libc::c_bool,你会使用什么?T为什么它对于所有可能尺寸的C99 bool(> = 1位)都是安全和便携的?
正如你已经联系到的那样,官方答案仍然"待定".这意味着保证正确的唯一可能性是:没有.
这是对的,尽管可能很难过.唯一真正安全的做法是将您转换bool为已知的固定大小的整数类型,例如u8,为了FFI的目的.这意味着你需要在两边编组.
实际上,我会继续使用bool我的FFI代码.正如人们所指出的那样,它神奇地排列在目前广泛使用的所有平台上.如果语言决定使boolFFI兼容,那么你很高兴.如果他们决定别的东西,如果他们没有引入棉绒让我们快速发现错误,我会非常惊讶.
也可以看看: