You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rust中调用预编译C静态库(.lib)中的函数

Rust 直接链接预编译 .lib 静态库解决方案

1 修正 build.rs 配置

不要使用相对路径,通过 Cargo 内置的环境变量拼接绝对路径避免寻址错误,链接库只需要指定纯库名,不需要路径、前缀、后缀:

fn main() {
    // CARGO_MANIFEST_DIR 是当前项目 Cargo.toml 所在的根目录
    let lib_path = format!("{}/my_c_project/cmake-build-debug", env!("CARGO_MANIFEST_DIR"));
    println!("cargo:rustc-link-search={}", lib_path);
    // MSVC 编译的静态库不需要加 lib 前缀,直接写原始库名即可
    println!("cargo:rustc-link-lib=static=my_c_project");
}

同时把你之前重命名的 libmy_c_project.lib 改回原来的 my_c_project.lib,lib 前缀是 Linux/macOS/MinGW 平台的静态库命名规则,MSVC 平台不需要。

2 修正 main.rs 的 extern 块声明

必须显式指定 extern "C",否则 Rust 会默认使用 Rust 调用约定查找符号,出现符号名不匹配的问题,不需要额外加 #[link] 指令,build.rs 已经处理了链接配置:

extern "C" {
    fn hello();
}

fn main() {
    unsafe {
        hello();
    }
}

3 确认工具链与库架构匹配

  • 如果你编译 .lib 用的是 MSVC 工具链,Rust 也要使用对应的 MSVC 工具链(比如 stable-x86_64-pc-windows-msvc),不能使用 GNU 工具链,二者的静态库格式不兼容。
  • 确认编译 .lib 的架构和 Rust 工具链架构一致,比如都是 64 位或者都是 32 位,架构不同也会出现找不到符号的问题。

4 常见问题说明

  • 注释掉 hello() 调用就能编译的原因:Rust 链接器默认会裁剪未使用的符号,没有调用 hello 的时候,链接器根本不会去查找这个符号,自然不会报错,不是链接逻辑没有执行。
  • build.rs 里 cargo: 开头的打印是给 Cargo 传递配置指令,只要语法没错就不会抛出错误,参数错误只会在链接阶段才会暴露。
  • 不要同时使用 build.rs 链接配置和 #[link] 指令,二者选其一即可,优先使用 build.rs 的方式,后续修改配置更灵活。

排查手段

如果按照上面的步骤还是报找不到符号,可以用 VS 自带的 dumpbin 工具查看 .lib 的导出符号:
dumpbin /symbols my_c_project.lib
在输出中查找 hello 函数是否存在,确认 C 代码编译的时候没有被优化掉,确实导出了对应符号。

内容的提问来源于stack exchange,提问作者Plegeus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 05:39:00