rust - 如何在编译时获取 const 的值?
问题描述
我的目标是创建一个 C API,用户需要提供一定大小的内存块。这个大小恰好是我的 rust 库中结构的大小,所以我想提取 rust 结构的大小并将其作为 C 宏放在头文件中。
问题是我正在交叉编译我的库,所以我无法在我的计算机上运行打印core::mem::size_of::<MyStruct>()
. 但是我可以将该值存储const
在我的库中的一个变量中。
有什么方法可以const
在编译时提取代表我的结构大小的这个变量的值,以便我可以将它粘贴到 C 头文件中?
解决方案
绝对不要这样做:
在一个新的 crate 中,导入有问题的类型,并创建一个返回其大小的函数:
#[no_mangle] pub fn size_of_mystruct() -> usize { std::mem::size_of::<MyStruct>() }
获取 LLVM-IR 输出:
CARGO_INCREMENTAL=0 cargo rustc -- --emit=llvm-ir -o ir
确保也添加该
--target
选项。这将创建一些文件,其中一个应该具有扩展名.ll
. 这CARGO_INCREMENTAL=0
很重要 - 没有它,它将创建大量.ll
文件,谁知道哪个是正确的!打开文件并搜索size_of_mystruct
. 你会发现这样的东西:; Function Attrs: uwtable define i64 @size_of_mystruct() unnamed_addr #0 !dbg !142 { start: ; call core::mem::size_of %0 = call i64 @_ZN4core3mem7size_of17hc5e3caf4d8826b98E(), !dbg !144 br label %bb1, !dbg !144
搜索此处调用的内部函数。(在这种情况下
_ZN4core3mem7size_of17hc5e3caf4d8826b98E
)。它看起来像这样:; core::mem::size_of ; Function Attrs: inlinehint uwtable define internal i64 @_ZN4core3mem7size_of17hc5e3caf4d8826b98E() unnamed_addr #1 !dbg !67 { start: %tmp_ret = alloca i64, align 8 store i64 40, i64* %tmp_ret, align 8, !dbg !87 %0 = load i64, i64* %tmp_ret, align 8, !dbg !87 br label %bb1, !dbg !87
这是重要的一点:
store i64 40
。结构是 40 字节!自动化流程!
等到整个过程神秘地中断。
推荐阅读
- button - ASP.NET Core MVC:我无法阻止后退按钮
- python - 在 pandas-python 中取消堆叠列
- flutter - Flutter 中的 RTCTokenBuilder Agora 保持说 invalidAppID
- flutter - FCM 自定义声音通知不适用于 IOS Xcode
- c# - 是否可以对 Angular 9 项目进行差异覆盖?
- c# - 用于匹配值数组或其他数组的正则表达式
- android - 关于 Glide 的 sizeMultiplier 的说明
- java - 使用 InheritableThreadLocal 的数据泄漏
- docker - 有没有办法从标准输入提供 docker-compose env-file?
- r - 我的 aggregate() 输出和 tidyverse 输出之间的区别