【发布时间】:2021-11-04 00:20:29
【问题描述】:
我有两个 C++ 源代码(a.cc、b.cc),一个将编译成共享库(a.dll),另一个将编译成可执行文件(b.exe)并链接a.dll,但 MSVC 链接器在没有 __declspec(dllimport) 的情况下无法正确链接 a.dll 中的符号。
a.cc
extern "C" int mysym;
// extern "C" __declspec(dllexport) int mysym;
int mysym = 123;
cl -std:c++17 -O2 -fp:fast -EHsc -I"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include" -I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared" -I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um" -DNOMINMAX -LD .\a.cc -Fe:a.dll -link -LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\x64" -LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64" -LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x64" -EXPORT:mysym
b.cc
#include <iostream>
using namespace std;
// this is OK
// extern "C" __declspec(dllimport) int mysym;
// this is wrong
extern "C" int mysym;
int main() {
// expect output 123
std::cerr << mysym << std::endl;
std::cerr << &mysym << std::endl;
return 0;
}
cl -std:c++17 -O2 -fp:fast -EHsc .\b.cc a.lib -I"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include" -I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared" -I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um" -DNOMINMAX -Fe:b.exe -link -LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\x64" -LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64" -LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x64"
当我执行b.exe时,命令输出一个随机数,而不是123。当我添加__declspec(dllimport) 时,该命令按预期工作。
为了弄清楚原因,我在b的构建命令中转储了-VERBOSE的日志,发现了一些线索:
// log without __declspec(dllimport)
Searching libraries
searching a.lib:
Found mysym
ref in b.obj
loaded a.lib(a.dll)
// log with __declspec(dllimport)
Searching libraries
searching a.lib:
Found mysym
ref in a.exp
loaded a.lib(a.dll)
似乎符号查找错误,我的问题是:
- 如果链接器未发现符号或符号查找错误,是否会产生链接错误,而不是将其链接到随机未初始化的地址?
- 我可以告诉编译器或链接器
mysym需要__declspec(dllimport)而不更改源代码吗?因为我的项目比较大,改源码是不可能的。
【问题讨论】:
标签: c++ windows visual-studio visual-c++ linker