在Rust中调用C库可以通过以下步骤实现:
创建Rust项目
使用`cargo new hello --lib`命令创建一个新的Rust库项目,并指定库类型为动态库(`cdylib`)。
编写Rust代码
在`lib.rs`中编写需要导出的Rust函数,并使用`[no_mangle]`属性确保函数名在链接时不会被改变。使用`extern "C"`来指定函数遵循C语言的调用约定。
```rust
[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
a + b
}
```
构建动态库
运行`cargo build`命令来构建项目,生成的动态库文件将位于`target/debug`目录下(在不同操作系统上,文件后缀可能不同)。
在C中使用Rust函数
编写一个C头文件,包含Rust函数的外部声明。
使用C编译器编译包含Rust函数声明的头文件和Rust生成的动态库,生成C共享库(如`.so`文件或`.dylib`文件)。
在C代码中链接生成的共享库,并调用Rust函数。
示例
Rust代码 (`lib.rs`)
```rust
[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
a + b
}
```
C头文件 (`hello.h`)
```c
ifndef HELLO_H
define HELLO_H
int add(int a, int b);
endif // HELLO_H
```
C代码 (`main.c`)
```c
include "hello.h"
include
int main() {
int result = add(3, 4);
printf("3 + 4 = %d\n", result);
return 0;
}
```
构建动态库
```sh
cargo build --release
```
编译和链接C代码
```sh
gcc -o main main.c -Ltarget/release -lhello
```
使用工具
为了简化C头文件的生成和Rust外部函数接口的创建,可以使用以下工具:
cbindgen:自动生成C/C++头文件,减少手动编写头文件的工作量。
bindgen:用于生成Rust绑定代码,特别是对于C++库。
注意事项
使用`unsafe`关键字时要格外小心,因为它允许执行任意代码,可能会导致安全问题。
确保Rust和C代码之间的数据类型和调用约定兼容。
在C代码中正确链接Rust生成的动态库,以便能够调用Rust函数。
通过以上步骤和工具,你可以在Rust项目中顺利调用C库。