Rust常量/静态可以暴露给C吗?

时间:2015-07-29 13:20:26

标签: c rust ffi

假设我有一个包含常量或静态的Rust API,例如i32。我想从C使用这个Rust API。从C方面,我想将该常量用作数组大小。我是否正确无法做到这一点?在我的C头文件中重新声明常量的最佳解决方案是为其余的Rust API提供声明吗?

更新 更具体地说,我使用的是不支持可变长度数组的编译器(Visual C ++ 2005)

2 个答案:

答案 0 :(得分:10)

你当然可以做到,至少在功能内部:

cnst.rs

#[no_mangle]
pub static X: i32 = 42;

cnstuse.c

#include <stdint.h>
#include <stdio.h>

extern const int32_t X;

int main() {
    char data[X];
    printf("%lu\n", sizeof(data));
    return 0;
}

汇编:

% rustc --crate-type=staticlib cnst.rs
note: link against the following native artifacts when linking against this static library
note: the order and any duplication can be significant on some platforms, and so may need to be preserved
note: library: System
note: library: pthread
note: library: c
note: library: m
% gcc -o cnstuse cnstuse.c libcnst.a
% ./cnstuse
42

但是,顶级数组声明不能将全局变量/常量用于大小,因此这只能在函数内部使用。

答案 1 :(得分:0)

  

更具体地说,我使用的是不支持可变长度数组的编译器(Visual C ++ 2005)

这需要在使用点定义(而不仅仅是声明)常量。此外,C对于构成可用作数组维的常量的限制比C ++有更多限制:基本上是整数文字(可以通过宏替换)和枚举数;与C ++不同,它没有整数常量(int const x),因此根据您编译的模式(C或C ++),您可能会受到限制。

rustc或Cargo中没有自动生成C文件的工具,这些符号仅在链接时导出并可用,而不是在编译时。

你很幸运,有一个解决方案,虽然它稍微麻烦一点。

Rust具有build.rs文件,该文件作为常规编译过程的一部分进行编译和执行。该文件可以包含生成其他文件的命令,因此完全可以:

  1. .rs文件
  2. 中一劳永逸地记下常量
  3. 通过build.rs文件以C格式生成“导出”此常量的C标头。