C 调用 Rust 使用示例

2024-06-20 language rust c/cpp

整理 C 调用 Rust 时需要注意的事项。

简介

最简单通过 C/CPP 调用 Rust 生成函数。

----- 新建Rust库,默认会添加add函数
cargo new hello --lib
----- 将函数修改为如下
#[no_mangle]
pub extern "C" fn hello() {
    println!("Hello World");
}
----- 同时修改Cargo.toml,增加如下内容,生成静态库和动态库
[lib]
crate-type = ["staticlib", "cdylib"]

修改后的函数增加了 no_mangle 这样函数名不会修改,可以直接通过符号调用;另外,通过 extern "C" 声明函数调用方式,核心就是调用函数时的出栈入栈方式。

然后通过 cargo build 编译即可,此时会在 src/target 目录下生成 libhello.solibhello.a 两个库。

对应的 C 实现 main.c 如下,如果是 CPP 则需要在声明时添加 extern "C" {...} 包含,否则会因为 CPP 的 mangle 导致连接时出现 undefined reference 的报错。

void hello();

int main(void)
{
	hello();
	return 0;
}

然后通过如下命令编译运行即可。

----- 使用动态库连接,运行时会同时要求动态库位置
gcc main.c -o test -L./hello/target/debug -lhello
LD_LIBRARY_PATH=./hello/target/release ./test
----- 或者使用静态库,此时可以直接运行
gcc main.c -o test ./hello/target/debug/libhello.a
./test