通过FFI将C99`bool`返回Rust的正确类型是什么? [英] What is the correct type for returning a C99 `bool` to Rust via the FFI?

查看:118
本文介绍了通过FFI将C99`bool`返回Rust的正确类型是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我和一位同事一直在努力思考如何通过FFI将bool<stdbool.h>(又称_Bool)返回给Rust.

A colleague and I have been scratching our heads over how to return a bool from <stdbool.h> (a.k.a. _Bool) back to Rust via the FFI.

我们有想要从Rust中使用的C99代码:

We have our C99 code we want to use from Rust:

bool
myfunc(void) {
   ...
}

我们使用extern C块让Rust知道myfunc:

We let Rust know about myfunc using an extern C block:

extern "C" {
    fn myfunc() -> T;
}

T应该是什么具体类型?

What concrete type should T be?

Rust在libc板条箱中没有c_bool,并且如果您在互联网上搜索,您会发现各种GitHub问题和RFC,人们可以在此进行讨论,但实际上并没有达成共识什么是正确且可移植的:

Rust doesn't have a c_bool in the libc crate, and if you search the internet, you will find various GitHub issues and RFCs where people discuss this, but don't really come to any consensus as to what is both correct and portable:

  • https://github.com/rust-lang/rfcs/issues/1982#issuecomment-297534238
  • https://github.com/rust-lang/rust/issues/14608
  • https://github.com/rust-lang/rfcs/issues/992
  • https://github.com/rust-lang/rust/pull/46156

据我所知:

  • C99中bool的大小没有定义,除了它必须至少足够大以存储true(1)和false(0)的事实.换句话说,至少要长一点.
  • 它甚至可能有点宽.
  • 其大小可能为已定义ABI .
  • >
  • The size of a bool in C99 is undefined other than the fact it must be at least large enough to store true (1) and false (0). In other words, at least one bit long.
  • It could even be one bit wide.
  • Its size might be ABI defined.

此注释建议如果C99 bool传递给函数作为参数或传递给函数作为返回值, bool小于C int,然后提升为与.在这种情况下,我们可以说Rust Tu32.

This comment suggests that if a C99 bool is passed into a function as a parameter or out of a function as the return value, and the bool is smaller than a C int then it is promoted to the same size as an int. Under this scenario, we can tell Rust T is u32.

好的,但是(出于某种原因)如果C99 bool为64位宽怎么办? u32仍然安全吗?也许在这种情况下,我们会截断4个最高有效字节,这很好,因为4个最低有效字节足以表示truefalse.

All right, but what if (for some reason) a C99 bool is 64 bits wide? Is u32 still safe? Perhaps under this scenario we truncate the 4 most significant bytes, which would be fine, since the 4 least significant bytes are more than enough to represent true and false.

我的推理正确吗?在Rust获得libc::c_bool之前,您将如何使用T?为什么它对于所有可能大小的C99 bool(> = 1位)都是安全且可移植的?

Is my reasoning correct? Until Rust gets a libc::c_bool, what would you use for T and why is it safe and portable for all possible sizes of a C99 bool (>=1 bit)?

推荐答案

截至

As of 2018-02-01, the size of Rust's bool is officially the same as C's _Bool.

这意味着bool是在FFI中使用的正确类型.

This means that bool is the correct type to use in FFI.

此答案的其余部分适用于做出正式决定之前的Rust版本

直到Rust获得libc::c_bool,您将如何使用T?为什么它对于所有可能大小的C99布尔型(> = 1位)安全且可移植?

Until Rust gets a libc::c_bool, what would you use for T and why is it safe and portable for all possible sizes of a C99 bool (>=1 bit)?

正如您已经链接到的一样,官方答案仍然是待定".这意味着唯一可以保证正确的可能性是:什么都没有.

As you've already linked to, the official answer is still "to be determined". That means that the only possibility that is guaranteed to be correct is: nothing.

是的,这很悲惨.唯一真正安全的方法是将您的bool转换为已知的固定大小的整数类型,例如u8以便进行FFI.这意味着您需要在两侧封送它.

That's right, as sad as it may be. The only truly safe thing would be to convert your bool to a known, fixed-size integral type, such as u8, for the purpose of FFI. That means you need to marshal it on both sides.

实际上,我会在我的FFI代码中继续使用bool.正如人们指出的那样,它神奇地排列在当前广泛使用的所有平台上.如果该语言决定使bool FFI兼容,那您就走了.如果他们决定采取其他措施,如果他们没有引入皮棉让我们迅速发现错误,我会感到非常惊讶.

Practically, I'd keep using bool in my FFI code. As people have pointed out, it magically lines up on all the platforms that are in wide use at the moment. If the language decides to make bool FFI compatible, you are good to go. If they decide something else, I'd be highly surprised if they didn't introduce a lint to allow us to catch the errors quickly.

另请参阅:

这篇关于通过FFI将C99`bool`返回Rust的正确类型是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆