Rust constant/static 可以暴露给 C 吗?
Can a Rust constant/static be exposed to C?
假设我有一个 Rust API,其中包含常量或静态变量,例如 i32。我想在 C 中使用这个 Rust API。在 C 方面,我想将该常量用作数组大小。我是正确的,没有办法做到这一点吗?在我的 C 头文件中重新声明常量的最佳解决方案是为 Rust 的其余部分提供声明 API?
更新:
更具体地说,我使用的编译器不支持可变长度数组 (Visual C++ 2005)
你肯定能做到,至少在函数内部:
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
但是,顶级数组声明不能使用全局 variables/constants 大小,因此这只能在函数内部使用。
To be more specific, I am using a compiler which does not support variable-length arrays (Visual C++ 2005)
这需要在使用时定义常量(而不仅仅是声明)。此外,对于什么构成可用作数组维度的常量,C 比 C++ 有更多限制:基本上是整数文字(可以通过宏替换)和枚举数;与 C++ 不同,它没有整数常量 (int const x
),因此根据您编译的模式(C 或 C++),您可能会受到限制。
rustc 或 Cargo 中没有自动生成 C 文件的工具,符号仅在 link 时导出和可用,在编译时不可用。
你还好,有解决办法,虽然稍微麻烦一些。
Rust 有一个 build.rs
文件,它作为常规编译过程的一部分被编译和执行。该文件可以包含生成其他文件的命令,因此完全可以:
- 在
.rs
文件中一劳永逸地写下常量
- 通过
build.rs
文件生成一个 C 头文件 "exporting" 这个 C 格式的常量。
假设我有一个 Rust API,其中包含常量或静态变量,例如 i32。我想在 C 中使用这个 Rust API。在 C 方面,我想将该常量用作数组大小。我是正确的,没有办法做到这一点吗?在我的 C 头文件中重新声明常量的最佳解决方案是为 Rust 的其余部分提供声明 API?
更新: 更具体地说,我使用的编译器不支持可变长度数组 (Visual C++ 2005)
你肯定能做到,至少在函数内部:
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
但是,顶级数组声明不能使用全局 variables/constants 大小,因此这只能在函数内部使用。
To be more specific, I am using a compiler which does not support variable-length arrays (Visual C++ 2005)
这需要在使用时定义常量(而不仅仅是声明)。此外,对于什么构成可用作数组维度的常量,C 比 C++ 有更多限制:基本上是整数文字(可以通过宏替换)和枚举数;与 C++ 不同,它没有整数常量 (int const x
),因此根据您编译的模式(C 或 C++),您可能会受到限制。
rustc 或 Cargo 中没有自动生成 C 文件的工具,符号仅在 link 时导出和可用,在编译时不可用。
你还好,有解决办法,虽然稍微麻烦一些。
Rust 有一个 build.rs
文件,它作为常规编译过程的一部分被编译和执行。该文件可以包含生成其他文件的命令,因此完全可以:
- 在
.rs
文件中一劳永逸地写下常量 - 通过
build.rs
文件生成一个 C 头文件 "exporting" 这个 C 格式的常量。