定义表示不透明 C 结构的 Rust 类型的交叉编译安全方法,其大小在编译时已知

Posted

技术标签:

【中文标题】定义表示不透明 C 结构的 Rust 类型的交叉编译安全方法,其大小在编译时已知【英文标题】:Cross-compile-safe way of defining a Rust type representing an opaque C struct whose size is known at compile-time 【发布时间】:2021-07-06 22:56:31 【问题描述】:

我需要定义一个 Rust 类型来反映一个不透明的 C 结构,其大小和对齐要求在编译时是已知的。一位乐于助人的人建议我生成类似

的代码
#[repr(C, align($ALIGNMENT_GOES_HERE))]
pub struct Foo(std::mem::MaybeUninit<[u8; $SIZE_GOES_HERE]>);

来自一个 C 程序,$SIZE_GOES_HERE 和朋友根据我从那里确定的内容填写。这很好用,但如果大小和对齐方式依赖于平台,则在交叉编译的情况下根本不可靠。

对此有什么可靠的解决方案吗? cc crate 看起来很有前途。

【问题讨论】:

@eggyal:这很有趣,非常感谢!但如果可能的话,我宁愿避免一个巨大的新依赖。 如果关键是要在目标机器的编译时确定这些大小和对齐方式,我无法在本地运行一次 :-) 条件编译路径是可能的,但这将是非常劳动密集型和脆弱的。不过感谢您的建议。 当然,bindgen 绝对是一种选择。我只是想知道是否可以在编译时以交叉编译安全的方式确定不透明 C 结构的大小和对齐方式。您对 bindgen 的建议很棒,但我的后续问题是,是否有可能引入一个巨大的新(构建)依赖项。这个问题的答案很可能是“不”。无论如何,欢迎您的建议 - 您无法理解我的想法,因为我没有在我的问题中指定“没有额外的构建dep”要求:-) 确定不需要提供布局? sizealignment 要求 应该足够了,对吧?这些我确实需要提供。因此,我的问题是:假设 C 编译器可以从可用的头文件中理解大小和对齐方式,我是否可以让 Rust 自动执行相同的操作(在面对交叉编译时不会变得脆弱) ? (您对 bindgen 可以解决这个问题的回答很好——但出于好奇,我也对不添加大的新构建deps 的建议感兴趣)。 我想我们应该停止在 cmets 中进行这种扩展讨论,但如果您将 bindgen 建议作为答案,我会接受。这样我们就可以帮助其他可能有同样问题的人:-) 【参考方案1】:

特定目标架构的给定结构的大小和对齐方式由结构的布局和目标架构的 ABI 决定。

如果 Rust 没有结构的布局,则它无法确定其大小或对齐方式——因此必须明确提供此信息。

但是,由于此信息依赖于目标,因此在编译之前提供它会将可能的目标限制为已硬编码的目标(例如,通过不同的定义,由条件编译选择)。

相反,有一个名为bindgen 的官方工具可以在编译时自动从 C 头文件生成适当的 Rust 绑定作为构建步骤。如果需要,可以将其配置为treat a type as an opaque blob of bytes。

【讨论】:

以上是关于定义表示不透明 C 结构的 Rust 类型的交叉编译安全方法,其大小在编译时已知的主要内容,如果未能解决你的问题,请参考以下文章

我可以将AS3代码或Flex项目交叉编译为本机C ++吗?

如何在Rust中的函数堆栈上放置C结构?

C语言开发函数库时利用不透明指针对外隐藏结构体细节

rust单元类型

保护不透明数据类型中的数据

什么定义了 C 中的不透明类型,它们什么时候需要和/或有用?