Rust常量/静态变量能够暴露给C语言吗?

13
假设我有一个Rust API,其中包含一个常量或静态变量,例如i32。 我想从C中使用这个Rust API,并将该常量用作数组大小。 我是正确的,没有办法做到这一点吗? 最好的解决方案是在提供其余Rust API声明的C头文件中重新声明该常量吗?
更新: 更具体地说,我正在使用不支持可变长度数组(Visual C++ 2005)的编译器。
2个回答

15

你肯定可以做到,至少在函数内部:

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
啊,对于支持可变长度数组的编译器来说这很好用,但是我的不行。我使用的是Visual C++ 2005编译器。我会更新我的问题以使其更具体。 - user1096614
在这种情况下,您只能使用基于预处理器的常量,因此很遗憾您无法使用在 Rust 侧定义的常量。 - Vladimir Matveev
如何在C中声明X而不初始化它?https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=eb9a09e43bf6495eb950fcea1a967ae6 https://stackoverflow.com/q/65292878 - user2284570

1
更具体地说,我正在使用一个不支持变长数组的编译器(Visual C++ 2005)。
这要求常量在使用点被定义(而不仅仅是声明)。此外,C对可以用作数组维度的常量有更多限制,基本上只有整数字面值(可以通过宏替换)和枚举器;不像C++那样有整数常量(int const x),因此根据您编译的模式(C或C++),您可能会受到限制。
在rustc或Cargo中没有自动生成C文件的功能,符号仅在链接时导出并可用,而不是在编译时。

你很幸运,有一个解决方案,不过它可能更加繁琐。

Rust提供了一个build.rs文件,它会在常规编译过程中被编译和执行。该文件可以包含生成其他文件的命令,因此完全可以:

  1. 一次性在.rs文件中写下常量
  2. 通过build.rs文件以C格式生成一个C头文件"导出"这个常量。

我将不得不在build.rs上进行一些尝试。我看过它,但为了获得尽可能简单的最小概念验证,我选择跳过它。 - user1096614

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接