理解 windows-targets crate
windows 和 windows-sys crate 依赖于 windows-targets crate 以获得链接器支持。windows-targets
crate 包含导入库,支持语义版本控制,并可选地支持 raw-dylib
。它为以下目标提供了显式导入库:
- i686_msvc
- x86_64_msvc
- aarch64_msvc
- i686_gnu
- x86_64_gnu
- x86_64_gnullvm
- aarch64_gnullvm
导入库包含链接器用于解析由 DLL 导出的函数的外部引用的信息。这允许操作系统在加载时识别特定的 DLL 和函数导出。导入库是工具链和架构特定的。换句话说,根据您是使用 MSVC 还是 GNU 工具链编译,以及您是为 x86 还是 ARM64 架构编译,需要不同的 lib 文件。请注意,导入库不包含任何代码,静态库则包含。
虽然 GNU 和 MSVC 工具链通常提供一些导入库来支持 C++ 开发,但这些 lib 文件通常不完整、缺失或完全错误。这可能导致非常难以诊断的链接器错误。windows-targets
crate 确保 windows
和 windows-sys
crate 定义的所有函数都可以链接,而无需依赖工具链分发的隐式 lib 文件。这确保了依赖项可以通过 Cargo 进行管理,并简化了交叉编译。windows-targets
crate 还包含版本特定的 lib 文件名,以确保语义版本兼容性。如果没有此功能,链接器将简单地选择第一个匹配的 lib 文件名,并无法解析任何缺失或不匹配的导入。
注意:通常,您根本不需要考虑
windows-targets
crate。windows
和windows-sys
crate 会自动依赖windows-targets
crate。只有在极少数情况下,您才需要直接使用它。
首先将以下内容添加到您的 Cargo.toml 文件中
[dependencies.windows-targets]
version = "0.52"
使用 link
宏定义您希望调用的外部函数
#![allow(unused)] fn main() { windows_targets::link!("kernel32.dll" "system" fn SetLastError(code: u32)); windows_targets::link!("kernel32.dll" "system" fn GetLastError() -> u32); }
根据需要使用任何 Windows API
fn main() { unsafe { SetLastError(1234); assert_eq!(GetLastError(), 1234); } }
默认情况下,link
宏将导致链接器使用捆绑的导入库。使用 windows_raw_dylib
Rust 构建标志编译将导致 Cargo 完全跳过下载导入库,而是使用 raw-dylib
自动解析导入。然后 Rust 编译器将直接创建导入条目。这无需更改任何代码即可工作。如果没有 windows-targets
crate,在链接器和 raw-dylib
导入之间切换需要非常复杂的代码更改。截至本文撰写之时,raw-dylib
功能尚未稳定。