是否可以使用 C 从 Rust 中构建的静态库中调用函数?



来自 Rust 的函数,构建为 C 语言中调用的静态库

// Rust
fn message() -> String
// C
int main() {
message()
} 

设置项目

像往常一样创建新的cargo库:

$ cargo new my_rust_library --lib

然后,您可以将cargo配置为发出系统库而不是其常规的 rust 目标:

[lib]
crate-type = ["cdylib"]      # dynamic lib
# crate-type = ["staticlib"] # static lib

构建 C API

可以将函数标记为extern "C",以告知编译器使用 C ABI。您还需要添加#[no_mangle]注释,以告诉编译器不要破坏此函数的名称:

#[no_mangle]
pub extern "C" fn message() {
println!("Hello C!")
}

连接

您可以像往常一样建造板条箱:

$ cargo build --release

cargo将在target/release目录中创建一个my_lib.somy_lib.a文件。这个库可以简单地由你的构建系统链接。但是,从 C 调用 Rust 函数需要一个头文件来声明函数签名。

每个extern fn都需要有一个相应的标头函数。

#[no_mangle]
pub extern "C" fn message() {}

将变成:

void message(void);

您可以使用cbindgen来自动化此过程,这是一个分析您的 Rust 代码并生成相应 C/C++ 标头的 crate 。您可以使用cargo安装它:

$ cargo install cbindgen

创建一个空的配置文件:

$ touch cbindgen.toml

并生成头文件:

$ cbindgen --config cbindgen.toml --crate my_rust_library --output my_header.h --lang c

现在你可以简单地包含标头,并从 C 调用 Rust 函数!

#include "my_header.h"
message()

最新更新