我需要一些有关 Rust 库到 C++ 应用程序的静态链接的建议。 我能够正确链接非常简单的代码,而无需 Rust 依赖项,并且我还能够动态链接代码(即使有依赖项)(*.dll),但我想将代码嵌入到 C++ *.exe ->静态链接会在 VS 构建过程中产生许多“无法解析的外部符号”错误。 为了演示这个问题,我在下面编写了一个非常简单的代码。它工作得很好,直到我取消注释 reqwest 库功能,然后只有动态链接(cdylib)开始工作...... 我缺少什么“技巧”?
测试/src/lib.rs:
// use reqwest::blocking::Client;
#[no_mangle]
pub extern "C" fn connect() -> i32 {
// let c = Client::new();
// c.get("http://www.google.com").send().expect("failed");
0
}
测试/cargo.toml:
[package]
name = "test"
version = "0.1.0"
edition = "2021"
[lib]
# crate-type = ["cdylib"]
crate-type = ["staticlib"]
[dependencies]
reqwest = { version = "0.12.9", features = ["blocking"]}
测试/测试.h:
extern "C" {
int32_t connect();
} // extern "C"
test_c/src/main.cpp:
#include <iostream>
#include "test.h"
int main()
{
int i = connect();
std::cout << "connect -> " << i << "\n";
}
我从 Visual Studio(2019 版)收到的错误如下所示:
Error LNK1120 77 unresolved externals test_c test_c.exe 1
Error LNK2001 unresolved external symbol __imp_accept test_c test.lib(std-2df1f22abef96888.std.1de697f09da2cdd5-cgu.0.rcgu.o) 1
Error LNK2001 unresolved external symbol __imp_accept test_c test.lib(socket2-220b4c5575b738d5.socket2.195adf5aa58b4623-cgu.1.rcgu.o) 1
Error LNK2001 unresolved external symbol __imp_accept test_c test.lib(socket2-220b4c5575b738d5.socket2.195adf5aa58b4623-cgu.2.rcgu.o) 1
Error LNK2001 unresolved external symbol __imp_accept test_c test.lib(socket2-220b4c5575b738d5.socket2.195adf5aa58b4623-cgu.0.rcgu.o) 1
Error LNK2001 unresolved external symbol __imp_AcceptSecurityContext test_c test.lib(reqwest-6591741496af5748.reqwest.d1308cb910735ad3-cgu.04.rcgu.o) 1
提前非常感谢您的任何提示!
您没有链接到标准 Windows API 库
Ws2_32
和 Secur32
。 (可能还有更多,这些只是来自您尚未解析的符号。)
如果动态链接,Rust DLL 本身会链接到它所需的 Win32 标准 API 库。
我不知道你到底是如何静态链接的(你没有提供太多关于你的构建系统的信息),但我的猜测是你只是将 Rust 代码链接到一个静态库,然后导入该静态库进入你的 C++ 版本,对吗?在这种情况下,所有 Rust 代码的静态库(希望还包括代码的 Rust 依赖项和 Rust 标准库)本身将具有 DLL 依赖项,并且您必须显式链接到您的代码所需的 DLL 依赖项包括在您的可执行文件中。
我不知道这是否可以以某种方式自动化,但是将所需的 Windows API DLL 显式添加到 C++ 项目链接到的外部 DLL 列表中应该可以实现此目的。