Rust FFI 跨平台引用cdylib动态库及Windows链接报错解决方案
跨平台适配Rust FFI链接Rust构建的C兼容cdylib的方案
核心适配代码
通过cfg_attr分平台指定链接参数,无需手动修改cargo生成的产物文件名,即可同时兼容两个平台的链接规则:
#[cfg_attr(target_os = "windows", link(name = "my_lib.dll", kind = "dylib"))] #[cfg_attr(target_os = "macos", link(name = "my_lib", kind = "dylib"))] extern "C" { // 声明需要导入的C接口函数 }
方案原理
- MacOS的ld链接器会自动匹配
lib<库名>.dylib格式的产物,传入不带前后缀的库名my_lib即可对应cargo生成的libmy_lib.dylib - Windows的MSVC链接器支持直接传入带
.dll后缀的库名参数,会自动匹配同目录下cargo生成的my_lib.dll.lib导入库,无需手动重命名文件
之前重命名操作报错的原因
你之前手动将
my_lib.dll.lib重命名为my_lib.lib后出现LINK : fatal error LNK1181: cannot open input file 'my_lib.lib'错误,核心原因通常是:
- 重命名后的文件未被放置在链接器的搜索路径中,导致链接器无法定位目标文件
- 即使重命名操作正确,若未在编译配置中指定对应搜索路径,链接器默认只会在系统库路径、Rust内置搜索路径中查找库文件
补充说明
- 采用编译期静态链接的方式时,Windows平台必须依赖对应的
.lib导入库文件才能完成链接,无法完全跳过该文件。如果确实不想依赖该导入库,可以改用libloading在运行时加载dll,绕过编译期链接流程,但需要自行处理函数符号加载、空值判断等逻辑 - 可在项目根目录的
build.rs中配置动态库搜索路径,无需将库文件移动到系统路径:fn main() { // 将cdylib的编译输出目录加入库搜索路径 println!("cargo:rustc-link-search=native=./target/debug"); println!("cargo:rustc-link-search=native=./target/release"); }
内容的提问来源于stack exchange,提问作者frankenapps
相关产品推荐
相关产品推荐

