rust - 如何在编译时获取 const 的值?

标签 rust compile-time

我的目标是创建一个 C API,要求用户提供一定大小的内存块。这个大小恰好是我的 Rust 库中结构的大小,因此我想提取 Rust 结构的大小并将其作为 C 宏放在头文件中。

问题是我正在交叉编译我的库,所以我无法在我的计算机上运行打印 core::mem::size_of::<MyStruct>() 的程序.但我可以将该值存储在 const 中我的库中的变量。

有什么方法可以提取这个 const 的值吗?表示编译时我的结构大小的变量,以便我可以将其粘贴到 C 头文件中?

最佳答案

绝对这样做:

  1. 在一个新的 crate 中,导入有问题的类型,并创建一个返回其大小的函数:

    #[no_mangle]
    pub fn size_of_mystruct() -> usize {
        std::mem::size_of::<MyStruct>()
    }
    
  2. 获取 LLVM-IR 输出:

    CARGO_INCREMENTAL=0 cargo rustc -- --emit=llvm-ir -o ir
    

    确保也添加 --target 选项。这将创建一些文件,其中一个应该具有扩展名 .llCARGO_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
    
  3. 搜索此处调用的内部函数。 (在这种情况下 _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
    
  4. 这是重要的一点:store i64 40。该结构是 40 个字节!

  5. 自动化流程!

  6. 等到整个过程神秘地中断。

关于rust - 如何在编译时获取 const 的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54477890/

相关文章:

java - Java 中提供编译时代码变体的任何机制?

c# - 有没有办法限制 C# 类中的函数只使用特定的签名?

generics - 特征的泛型类型和泛型关联类型有什么区别?

rust - 为什么 7.4 章片段中定义了 `thread_rng`

c++ - 如何在编译时确认自动推断类型的假设? (即 static_assert 样式

c# - 说服 C# 编译器执行将在成员返回后停止

java - 获取java类的编译时间戳

rust - 是否可以遍历元组?

rust - 创建拥有一些中间数据并指向它的迭代器的惯用方式是什么?

closures - "error: closure may outlive the current function"但它不会比它长寿