我正在尝试制作一个使用MSVC工具链与libusb静态链接的Rust程序,但它在运行时会因缺少DLL而崩溃:
error: process didn't exit successfully: `target\debug\test_libusb.exe` (exit code: 0xc0000135, STATUS_DLL_NOT_FOUND)
我使用Dependency Walker发现丢失的DLL是LIBUSB-1.0.DLL。将其添加到项目中可以解决此问题,因此可以动态链接所有内容,但是我想避免这种解决方案。
我的出发点是这个libusb-sys crate,但是由于它不起作用,我制作了一个更简单的类似板条箱。我从vcpkg获得了libusb。
libusb-sys / src / lib.rs
extern crate libc;
use libc::c_char;
#[repr(C)]
pub struct libusb_version {
pub major: u16,
pub minor: u16,
pub micro: u16,
pub nano: u16,
pub rc: *const c_char,
pub describe: *const c_char,
}
#[link(name = "libusb-1.0", kind = "static")]
extern "C" {
pub fn libusb_get_version() -> *const libusb_version;
}
libusb-sys / Cargo.toml
[package]
name = "libusb-sys"
version = "0.1.0"
build = "build.rs"
link = "libusb-1.0"
[dependencies]
libc = "0.2"
libusb-sys / build.rs
fn main() {
println!("
cargo:rustc-link-lib=static=libusb-1.0
cargo:rustc-link-search=native=C:/vcpkg/packages/libusb_x64-windows/lib")
}
然后我在程序的箱子上使用了它:
test_libusb / src / main.rs
extern crate libusb_sys as ffi;
fn main() {
unsafe {
let version = ffi::libusb_get_version();
println!(
"libusb v{}.{}.{}.{}",
(*version).major,
(*version).minor,
(*version).micro,
(*version).nano
);
}
}
test_libusb / Cargo.toml
[package]
name = "test_libusb"
version = "0.1.0"
[dependencies]
"libusb-sys" = { path = "../libusb-sys" }
如果有帮助,这里是整个编译器的输出:
G:\programming\rust\test_libusb> cargo run --verbose
Compiling libc v0.2.58
Compiling libusb-sys v0.1.0 (G:\programming\rust\libusb-sys)
Running `rustc --crate-name build_script_build C:\Users\slysherz\.cargo\registry\src\github.com-1ecc6299db9ec823\libc-0.2.58\build.rs --color always --crate-type bin --emit=dep-info,link -C debuginfo=2 --cfg "feature=\"default\"" --cfg "feature=\"std\"" -C metadata=f83941a94611be11 -C extra-filename=-f83941a94611be11 --out-dir G:\programming\rust\test_libusb\target\debug\build\libc-f83941a94611be11 -L dependency=G:\programming\rust\test_libusb\target\debug\deps --cap-lints allow`
Running `rustc --crate-name build_script_build G:\programming\rust\libusb-sys\build.rs --color always --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=71e53c2aee584c72 -C extra-filename=-71e53c2aee584c72 --out-dir G:\programming\rust\test_libusb\target\debug\build\libusb-sys-71e53c2aee584c72 -C incremental=G:\programming\rust\test_libusb\target\debug\incremental -L dependency=G:\programming\rust\test_libusb\target\debug\deps`
Running `G:\programming\rust\test_libusb\target\debug\build\libusb-sys-71e53c2aee584c72\build-script-build`
Running `G:\programming\rust\test_libusb\target\debug\build\libc-f83941a94611be11\build-script-build`
Running `rustc --crate-name libc C:\Users\slysherz\.cargo\registry\src\github.com-1ecc6299db9ec823\libc-0.2.58\src\lib.rs --color always --crate-type lib --emit=dep-info,link -C debuginfo=2 --cfg "feature=\"default\"" --cfg "feature=\"std\"" -C metadata=b67580e06366e753 -C extra-filename=-b67580e06366e753 --out-dir G:\programming\rust\test_libusb\target\debug\deps -L dependency=G:\programming\rust\test_libusb\target\debug\deps --cap-lints allow --cfg libc_priv_mod_use --cfg libc_union --cfg libc_const_size_of --cfg libc_align --cfg libc_core_cvoid --cfg libc_packedN`
Running `rustc --crate-name libusb_sys G:\programming\rust\libusb-sys\src\lib.rs --color always --crate-type lib --emit=dep-info,link -C debuginfo=2 -C metadata=94e8ef72b03c18f5 -C extra-filename=-94e8ef72b03c18f5 --out-dir G:\programming\rust\test_libusb\target\debug\deps -C incremental=G:\programming\rust\test_libusb\target\debug\incremental -L dependency=G:\programming\rust\test_libusb\target\debug\deps --extern libc=G:\programming\rust\test_libusb\target\debug\deps\liblibc-b67580e06366e753.rlib -L native=C:/vcpkg/packages/libusb_x64-windows/lib -l static=libusb-1.0`
Compiling test_libusb v0.1.0 (G:\programming\rust\test_libusb)
Running `rustc --crate-name test_libusb src\main.rs --color always --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=8f2bb1a8f56e2223 -C extra-filename=-8f2bb1a8f56e2223 --out-dir G:\programming\rust\test_libusb\target\debug\deps -C incremental=G:\programming\rust\test_libusb\target\debug\incremental -L dependency=G:\programming\rust\test_libusb\target\debug\deps --extern libusb_sys=G:\programming\rust\test_libusb\target\debug\deps\liblibusb_sys-94e8ef72b03c18f5.rlib -L native=C:/vcpkg/packages/libusb_x64-windows/lib`
Finished dev [unoptimized + debuginfo] target(s) in 1.20s
Running `target\debug\test_libusb.exe`
error: process didn't exit successfully: `target\debug\test_libusb.exe` (exit code: 0xc0000135, STATUS_DLL_NOT_FOUND)
即使使用VS 2017从头开始编译libusb之后,我仍然收到链接错误:
= note: test_libusb-528eb6acc7e5c681.3w5rrhap2r2yw5if.rcgu.o : error LNK2019: unresolved external symbol libusb_get_version referenced in function _ZN11test_libusb4main17hcb0c36db62706c3bE
G:\programming\rust\test_libusb\target\debug\deps\test_libusb-528eb6acc7e5c681.exe : fatal error LNK1120: 1 unresolved externals
当我直接从第一个板条箱调用此函数时,它仍然起作用。
我最近开始学习Rust,所以我不确定这是如何工作的。为什么Rust在这种情况下会尝试加载DLL?
答案 0 :(得分:0)
@Shepmaster是正确的,用于vcpkg的libusb:x64-windows三元组仅包含尝试从DLL调用真实函数的定义。
我试图从一个简单的C程序加载该库,却得到了完全相同的错误:
test.c
#include "C:\vcpkg\installed\x64-windows\include\libusb-1.0\libusb.h"
int main()
{
const struct libusb_version *version = libusb_get_version();
printf("Version %d.%d.%d", version->major, version->minor, version->micro);
}
编译为:
cl test.c /link C:\vcpkg\installed\x64-windows\lib\libusb-1.0.lib
导致相同的缺少DLL错误。但是,如果我使用不同的libusb:x64-windows-static三元组:
test.c
#pragma comment(lib, "Advapi32.lib")
#include "C:\vcpkg\installed\x64-windows-static\include\libusb-1.0\libusb.h"
int main()
{
const struct libusb_version *version = libusb_get_version();
printf("Version %d.%d.%d", version->major, version->minor, version->micro);
}
编译为:
cl test.c /link C:\vcpkg\installed\x64-windows-static\lib\libusb-1.0.lib
工作正常:
>test.exe
Version 1.0.22
总结起来,如果您想将Rust程序与libusb静态链接,请下载vspkg并安装
vcpkg.exe install libusb:x64-windows-static
。
设置一个指向LIBUSB_DIR
的环境变量C:\vcpkg\installed\x64-windows-static
并将其放入您的
Cargo.toml :
[dependencies]
libusb = "0.3"
libusb-sys = "0.2.3"
[patch.crates-io]
"libusb-sys" = { git = "https://github.com/cmsd2/libusb-sys" }