Rust 调用 C 动态链接库
计算学徒
2024年12月16日 19:53
收录于文集
共106篇

创建一个 C 动态链接库

创建一个 CMake 项目, 配置 CMakeLists.txt 如下:

代码块
C++
自动换行
复制代码
cmake_minimum_required(VERSION 3.25.0)
project(test VERSION 0.1.0 LANGUAGES C CXX)

# 自动导出函数
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS on)

# 创建动态链接库 DLL 
add_library(test SHARED test.cpp)
复制成功

代码文件 test.cpp 如下:

代码块
C++
自动换行
复制代码
extern "C" double plus2(double x) { return x + 2; }
复制成功

上述代码中定义了一个函数 plus2. 注意函数签名前的 extern "C", 这个表示采用 C 语言规范导出符号, 不加的话导出的函数符号就是乱七八糟的样子.

编译之后会生成一个 test.dll 的动态链接库文件.

在 Rust 中调用动态链接库

创建一个 Rust 测试项目:

代码块
Shell
自动换行
复制代码
cargo new loaddll
复制成功

在项目配置文件 Cargo.toml 中添加 libloading 依赖:

代码块
Shell
自动换行
复制代码
[dependencies]
libloading="0.8"
复制成功

Rust 源代码 main.rs 文件编辑如下:

代码块
Rust
自动换行
复制代码
fn call_dll() -> Result<f64, Box<dyn std::error::Error>> {
    unsafe {
        let lib = libloading::Library::new("test.dll")?;
        let plus2: libloading::Symbol<unsafe extern "C" fn(f64) -> f64> = lib.get(b"plus2")?;
        Ok(plus2(3.0))
    }
}
fn main() {
    println!("plus2(3) = {}", call_dll().unwrap());
}
复制成功

函数 call_dll 就是调用动态链接库的函数, lib 是要调用的动态链接库, plus2 是动态链接库中导出的函数.

将 test.dll 复制到 target/Debug 文件夹中, 然后编译运行 rust 项目会输出如下结果:

代码块
Rust
自动换行
复制代码
......
plus2(3) = 5
复制成功

这说明 Rust 成功调用了动态链接库中导出的函数 plus2.

说明

Rust 中的 libloading 库是跨平台的, 类似的代码也可以在 Linux 或者 Mac 操作系统中调用对应平台的动态链接库 (.so/.dylib), 非常方便.