首页 > 解决方案 > Rust ffi 以跨平台方式包含动态库

问题描述

我想在带有 FFI 的 Rust 中包含一个动态 C 库。

该库实际上也是用 Rust 构建的,但公开了一个 C 接口,因此它也可以从其他语言中使用。cdylib当我用 cargo构建库(类型:)时,我.dylib在 MacOS 上得到 a ,在 windows 上得到.dll一个文件。.dll.lib这些库也有不同的名称,源自项目名称(libmy_lib.dylib在 MacOS 和my_lib.dllWindowsmy_lib.dll.lib上)。

我想以跨平台的方式引用这些文件。因为目前我必须使用

#[link(name = "my_lib.dll", kind = "dylib")]

在 Windows 上,而在 MacOS 上我需要使用

#[link(name = "my_lib", kind = "dylib")]

我已经尝试将其重命名my_lib.dll.libmy_lib.lib,但我仍然收到链接器错误,说

LINK : fatal error LNK1181: cannot open input file 'my_lib.lib'

如何引用这些文件,以便我可以将我的代码用于 Mac 和 Windows?如果只有标签才有可能,cfg_attr我也会接受。理想情况下,如果可能的话,我还想摆脱.libWindows 的文件。

标签: rustcross-platformrust-cargo

解决方案


你可以使用 crate libloading

例子:

let lib = unsafe {
    #[cfg(unix)]
    let path = "mylib.so";
    #[cfg(windows)]
    let path = "mylib.dll";
    libloading::Library::new(path).expect("Failed to load library")
};
let func: libloading::Symbol<unsafe extern fn() -> u32> = unsafe {
     lib.get(b"my_func").expect("Failed to load function `my_func`")
};
// Can call func later while `lib` in scope

推荐阅读