在 C 代码中调用 Rust 代码,需要我们将 Rust 源代码打包为静态库文件。在 C 代码编译时,链接进去。
1、创建静态库
1.1、在命令行使用 cargo init --lib mylog
建立 lib 库。添加以下代码到 src/lib.rs 中:
1 #![crate_type = "staticlib"] 2 3 extern crate libc; 4 5 use libc::{c_int, c_char}; 6 use std::ffi::CStr; 7 8 #[repr(C)] 9 pub struct RustLogMessage { 10 id: c_int, 11 msg: *const c_char 12 } 13 14 #[no_mangle] 15 pub extern "C" fn rust_log(msg: RustLogMessage) { 16 let s = unsafe { CStr::from_ptr(msg.msg)}; 17 println!("id:{} message: {:?}", msg.id, s); 18 }
1.2、在 Cargo.toml 文件中添加以下代码,生成静态库文件:
[package] name = "mylog" version = "0.1.0" edition = "2021" [lib] name = "rust_log" crate-type = ["staticlib"] path = "src/lib.rs" [dependencies] libc = "0.2"
1.3、编译静态库,生成的静态库在src/target/release目录下,具体编译命令如下:
cargo build --release
2、使用cbindgen生成静态库头文件
2.1 新建 cbindgen.toml
文件,添加:language = "C"
默认已经安装了cbindgen。
2.2 cbindgen生成头文件:
cbindgen --config cbindgen.toml --crate mylog --output rust_log.h
生成的文件内容如下:
#include <stdarg.h> #include <stdbool.h> #include <stdint.h> #include <stdlib.h> typedef struct RustLogMessage { int id; const char *msg; } RustLogMessage; void rust_log(struct RustLogMessage msg);
3、新建C语言代码并编译
3.1 新建C语言代码, mymain.c:
#include <stdio.h> #include <stdlib.h> #include "rust_log.h" // include header file int main() { for (int i = 0; i < 10; i++) { RustLogMessage msg = { id : i, msg : "string in C language\n", }; rust_log(msg); } return 0; }
3.2 编译:
gcc -o main mymain.c -I. -Lmylog/target/release -lrust_log -ldl -lpthread -Wl,-gc-section
3.3 运行程序,输出如下:
id:0 message: "string in C language\n" id:1 message: "string in C language\n" id:2 message: "string in C language\n" id:3 message: "string in C language\n" id:4 message: "string in C language\n" id:5 message: "string in C language\n" id:6 message: "string in C language\n" id:7 message: "string in C language\n" id:8 message: "string in C language\n" id:9 message: "string in C language\n"