Rust调用C动态库
环境
rust: 1.83.0(2024-11-26)
bindgen: 0.71.1
cmake: 3.26.41. rust bindgen
bindgen 是一个能自动为 C(或 C++)库生成 Rust 绑定的辅助库和命令行工具。C++ (目前)的支持并不完整。
也就是说,bindgen 可以作为一个 crate,与 Cargo 的 build.rs 机制配合,根据 C/C++ 的头文件(.h, .hpp),在构建阶段,编译主体 Rust 代码之前,自动生成 Rust 绑定文件。
2. 安装bindgen
cargo install bindgen-cli3. 编写及编译C静态库
- 
example.h #ifndef EXAMPLE_H 
 #define EXAMPLE_H#ifdef _WIN32 
 #define DLL_EXPORT __declspec(dllexport)
 #else
 #define DLL_EXPORT
 #endifDLL_EXPORT int add(int a, int b); #endif 
- 
example.c #include "example.h" int add(int a, int b) 
 {
 return a + b;
 }
- 
CMakeLists.txt cmake_minimum_required(VERSION 3.8.2) project(example) add_library(${PROJECT_NAME} SHARED example.c) add_library(${PROJECT_NAME} STATIC example.c)
生成c动态库
$ cmake -B bin
$ cmake --build bin --config Release4. bindgen生成rust绑定文件
bindgen需要用到libcang,设置环境变量LIBCLANG_PATH
set LIBCLANG_PATH=D:/Program Files/LLVM/binbindgen example.h -o bindings.rs5. rust调用绑定文件
目录结构
$ tree
.
+--- bin
|   +--- Release
|   |   +--- example.dll
|   |   +--- example.lib
+--- bindings.rs
+--- CMakeLists.txt
+--- example
|   +--- Cargo.toml
|   +--- example.lib
|   +--- src
|   |   +--- main.rs
|   +--- target
|   |   +--- release
|   |   |   +--- example.dll
|   |   |   +--- example.exe
+--- example.c
+--- example.h- 
新建example项目 cargo new example 
- 
复制example.lib到example目录 cmake -E copy bin/Release/example.lib example 
- 
修改example/src/main.rs mod bindings { 
 include!("../../bindings.rs");
 }use bindings::*; #[link(name = "example")] 
 extern "C" {}fn main() { 
 unsafe {
 let sum = add(1, 2);
 println!("1 + 2 = {}", sum);
 }
 }
编译
cd example
cargo build -r运行
拷贝example.dll到程序运行目录
cmake -E copy bin/Release/example.dll example/target/release执行
$ cargo run -r
    Finished `release` profile [optimized] target(s) in 0.03s
     Running `target\release\example.exe`
1 + 2 = 3