构建调用Win32 GUID operator==的动态库时出现LNK2001错误求解释
GUID比较运算符在动态库构建时的链接错误分析
问题重现
测试代码
// test.cpp #include <mfapi.h> bool CompareGUID() { GUID a; GUID b; return a == b; }
CMake配置
# CMakeLists.txt cmake_minimum_required(VERSION 3.6) project (Demo) # C++14标准 set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) # 目标定义 add_library (lib test.cpp) add_executable (main main.cpp) target_link_libraries(main lib)
编译输出
➜ build Import-VisualStudioVars 2017 -Architecture x86 ********************************************************************** ** Visual Studio 2017 Developer Command Prompt v15.9.50 ** Copyright (c) 2017 Microsoft Corporation ********************************************************************** [vcvarsall.bat] Environment initialized for: 'x86' ➜ build cmake .. -G "Ninja" -DBUILD_SHARED_LIBS=OFF -- The C compiler identification is MSVC 19.16.27048.0 -- The CXX compiler identification is MSVC 19.16.27048.0 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x86/cl.exe - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x86/cl.exe - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Configuring done -- Generating done -- Build files have been written to: D:/Repos/misc/TestMfDynamic/build ➜ build ninja [4/4] Linking CXX executable main.exe ➜ build cmake .. -G "Ninja" -DBUILD_SHARED_LIBS=ON -- Configuring done -- Generating done -- Build files have been written to: D:/Repos/misc/TestMfDynamic/build ➜ build ninja [2/3] Linking CXX shared library lib.dll FAILED: lib.dll lib.lib cmd.exe /C "cmd.exe /C "C:\Users\zgzf1\scoop\apps\cmake\3.24.0\bin\cmake.exe -E __create_def D:\Repos\misc\TestMfDynamic\build\CMakeFiles\lib.dir\.\exports.def D:\Repos\misc\TestMfDynamic\build\CMakeFiles\lib.dir\.\exports.def.objs && cd D:\Repos\misc\TestMfDynamic\build"" && C:\Users\zgzf1\scoop\apps\cmake\3.24.0\bin\cmake.exe -E vs_link_dll --intdir=CMakeFiles\lib.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100226~1.0\x86\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100226~1.0\x86\mt.exe --manifests -- C:\PROGRA~2\MICROS~2\2017\COMMUN~1\VC\Tools\MSVC\1416~1.270\bin\Hostx86\x86\link.exe /nologo CMakeFiles\lib.dir\test.cpp.obj /out:lib.dll /implib:lib.lib /pdb:lib.pdb /dll /version:0.0 /machine:X86 /debug /INCREMENTAL /DEF:CMakeFiles\lib.dir\.\exports.def kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ." LINK Pass 1: command "C:\PROGRA~2\MICROS~2\2017\COMMUN~1\VC\Tools\MSVC\1416~1.270\bin\Hostx86\x86\link.exe /nologo CMakeFiles\lib.dir\test.cpp.obj /out:lib.dll /implib:lib.lib /pdb:lib.pdb /dll /version:0.0 /machine:X86 /debug /INCREMENTAL /DEF:CMakeFiles\lib.dir\.\exports.def kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:CMakeFiles\lib.dir/intermediate.manifest CMakeFiles\lib.dir/manifest.res" failed (exit code 1120) with the following output: exports.def : error LNK2001: lib.lib : fatal error LNK1120: 1 ninja: build stopped: subcommand failed.
现象与临时修复
- 构建静态库时一切正常,链接生成可执行文件无问题
- 构建动态库时出现LNK2001/LNK1120链接错误
- 已找到两种修复方案:
- 将头文件从
<mfapi.h>替换为<guiddef.h> - 将
a == b替换为IsEqualGUID(a, b)
- 将头文件从
疑问与分析尝试
对比静态库和动态库编译后的汇编代码,仅有的差异是:
静态库版本调用:
call bool operator==(_GUID const &,_GUID const &)
动态库版本调用:
call ==
无法解释该差异导致链接错误的原因,需要详细的原理性解释。
内容的提问来源于stack exchange,提问作者xyz1001
相关产品推荐
相关产品推荐

