我的目标是创建一个C API,要求用户提供一定大小的内存块。这个大小恰好是我的rust库中一个结构的大小,因此我想提取rust结构的大小并将其作为C宏放置在头文件中。
问题是我正在交叉编译我的库,所以我无法在打印core::mem::size_of::<MyStruct>()
的计算机上运行程序。但是我可以将该值存储在库中的const
变量中。
有什么方法可以在编译时提取表示我的结构大小的const
变量的值,以便可以将其粘贴到C头文件中?
答案 0 :(得分:1)
一定要 不 这样做:
在新的包装箱中,导入有问题的类型,并创建一个返回其大小的函数:
#[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个字节!
使过程自动化!
等待,直到整个过程神秘地中断。
答案 1 :(得分:0)
我认为从相反的方向解决这个问题会更明智:在 .h
文件中定义一个 C 结构,您将与您的库一起分发以供消费者使用,然后声明结构 {{1} } 在 Rust 中(您甚至可以让 bindgen 从 #[repr(C)]
自动为您生成声明,作为您构建的一部分)。