有没有办法导出 C 静态库中的函数?

Is there a way to export functions in C static library?

我正在用 Rust 测试一些 C 代码,但只对 windows 上的 C 静态库生锈 link。

问题是导出的 C 函数只导出到动态库,而不是静态库,因为我不能在 Rust 中使用 dll,所以我真的不能 link没有导出符号的库(如果我尝试这样做,rust 会抱怨未解析的引用)。

我试过的一些东西:

代码:

C:

// Note this is compiled with CMake to generate both a DyLib and a Static Lib.

#define EXPORT __declspec (dllexport)

EXPORT int my_func (void) {
    return 3;
}

生锈:

// build.rs:

fn main () {
    println!("cargo:rustc-link-search=native=path/to/my/lib");
}

// lib.rs:

#[cfg (test)]
mod tests;

// No *-sys crate for simplicity
pub mod sys {
    #[link (name = "my_lib")] // since Windows msvc linking is based on static libs, no matter what it is going to search for a static lib anyway...
    extern {
        pub fn my_func () -> i32; // libc::c_int is an alias to i32 on my machine
    }
}

// tests.rs:

use crate::sys;

#[test]
fn my_func_works () {
    assert_eq!(3, unsafe { sys::my_func () });
}

这超出了这个答案的范围,但这就是为什么属性和 declspecs 对软件工作如此不利。

如果你有图书馆;该库有一些 names 具有 全局 范围。例如,您可以有一个名为 ShaveMyBall 的程序来为足球赛前打扮。在库中,ShaveMyBall 可能只是存在,但您可能对与外部链接有一些要求,因此 ShaveMyBall 可能需要以 MyHairyBits_.

作为前缀

这种相反的要求可以很容易地通过符号操作实用程序来解决,而不是编程语言之间的怪异基础设施。一些简单的目标文件操作可以将 ShaveMyBall 更改为 MyHairyBits_ShaveMyBall.

但是,如果你坚持使用奇怪的、定义不明确的,甚至更糟的,由标准委员会部分定义的,你最终会得到一些有时可能有用的东西,这除了让你为微软收购做好准备之外, 通常是任何公司的丧钟。

在您的构建脚本中,您告诉 cargo 在哪里寻找您的库,但您从未告诉它实际 使用图书馆。您需要将此添加到您的 build.rs:

println!("cargo:rustc-link-lib=native=my_lib.lib");

请注意,货物文档中有关于 rustc-link-search 的说明(强调我的):

The rustc-link-search instruction tells Cargo to pass the -L flag to the compiler to add a directory to the library search path.

大约 rustc-link-lib:

The rustc-link-lib instruction tells Cargo to link the given library using the compiler's -l flag.