假设我有一个包含常量或静态的Rust API,例如i32。我想从C使用这个Rust API。从C方面,我想将该常量用作数组大小。我是否正确无法做到这一点?在我的C头文件中重新声明常量的最佳解决方案是为其余的Rust API提供声明吗?
更新 更具体地说,我使用的是不支持可变长度数组的编译器(Visual C ++ 2005)
答案 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
文件,该文件作为常规编译过程的一部分进行编译和执行。该文件可以包含生成其他文件的命令,因此完全可以:
.rs
文件build.rs
文件以C格式生成“导出”此常量的C标头。