Rust 如何调用处理 C 'int' 的 API?

How does Rust call APIs that deal in C 'int'?

代替 C 几十年来积累的杂乱无章的整数类型集合,Rust 有一组清晰有序的有符号和无符号整数类型,例如 i32 用于有符号 32 位整数;在大多数平台上,这也是 C 的 int 所代表的,尽管 C 不保证这一点。

当 Rust 试图调用一个 API 定义时会发生什么,不是根据绝对整数大小,而是根据“C int,无论这个平台上可能是什么” ?例如,经典的 Unix 文件 I/O(readwrite 等)以小整数标识文件;在大多数平台上,它们是带符号的 32 位整数,但可移植的 C 代码通常将它们称为 int(而不是 int32_t),因为那是 API 的定义方式;至少在理论上是可能的,例如未来的操作系统可能会将 int 定义为 64 位,并带来 API。

可移植的 Rust 代码如何处理它?是不是只是抱着 i32 和现在使用的平台相匹配的态度就够了?或者它还有别的作用吗?

What happens when Rust is trying to call an API defined, not in terms of an absolute integer size, but in terms of "C int, whatever that may be on this platform"?

Rust 适当地定义了 c_int 类型和各种其他 C type aliases used in FFI declarations in the raw::os namespace to support this. This module uses cfg directives to detect the platform and architecture and define these types 以匹配等效的 C 类型。这些存在于 intlong

这样,通过使用这些中性声明,您的代码在 C 的 int 可能不同的不同平台上重建时仍然可移植。

How does portable Rust code handle it? Does it just take the attitude that i32 matches the platforms in use today, and that's good enough? Or does it do something else?

The libc module defines its own c_int which does assume i32, presumably for historical reasons. There is an interesting RFC which details libc及其演变。

it is at least theoretically possible that e.g. a future operating system might define int as 64-bit

当然;在这种情况下,可以为此 OS 添加一个 #cfg[] 子句以使其成为 64 位,从而保持模块的源兼容性。