有没有办法导出 C 静态库中的函数?
Is there a way to export functions in C static library?
我正在用 Rust 测试一些 C 代码,但只对 windows 上的 C 静态库生锈 link。
问题是导出的 C 函数只导出到动态库,而不是静态库,因为我不能在 Rust 中使用 dll,所以我真的不能 link没有导出符号的库(如果我尝试这样做,rust 会抱怨未解析的引用)。
我试过的一些东西:
正常 linking: 这些曾经用于编译,但我把它弄丢了,因为所有其他正常的都出错了。
静态库link用动态库编辑:可以,但是没有用,导出的符号也没有出现在dumpbin /exports
,或者静态库依赖动态库。
静态 link 到对象 link 到动态:什么
代码:
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.
我正在用 Rust 测试一些 C 代码,但只对 windows 上的 C 静态库生锈 link。
问题是导出的 C 函数只导出到动态库,而不是静态库,因为我不能在 Rust 中使用 dll,所以我真的不能 link没有导出符号的库(如果我尝试这样做,rust 会抱怨未解析的引用)。
我试过的一些东西:
正常 linking: 这些曾经用于编译,但我把它弄丢了,因为所有其他正常的都出错了。
静态库link用动态库编辑:可以,但是没有用,导出的符号也没有出现在
dumpbin /exports
,或者静态库依赖动态库。静态 link 到对象 link 到动态:什么
代码:
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.