gpt4 book ai didi

c++ - MSVC - 可执行文件构建正确但 DLL 不正确,缺少符号和冲突的依赖项 - SSCCE/Repro

转载 作者:太空宇宙 更新时间:2023-11-04 04:15:41 29 4
gpt4 key购买 nike

我这里有一个工作的可执行文件,我正在尝试从相同的代码构建一个 DLL,但是我遇到了一些奇怪的错误,并且在多次尝试错误后设法查明了罪魁祸首,我决定要求帮助,因为我现在真的被困住了。我在我的代码中静态链接了 SDL2 和 Cimgui(Dear Imgui C Wrapper),可执行文件工作得很好:

#include "imgui/imgui.h"
#include "cimgui.h"
#pragma comment(lib, "cimgui.lib")

#include "SDL.h"
#undef main
#pragma comment(lib, "SDL2-staticd.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "imm32.lib")
#pragma comment(lib, "version.lib")

void main()
{
SDL_Init(0);
igCreateContext(0);
printf("OK");
}

现在我将项目切换到 DLL(我禁用了 /IMPLIB 选项以确保链接命令中的唯一区别/DLL 和扩展)。当我尝试构建时,我收到有关 cimgui.lib 的错误,例如:

cimgui.lib(imgui_draw.obj) : error LNK2001: unresolved external symbol memcmp
cimgui.lib(imgui_widgets.obj) : error LNK2001: unresolved external symbol memcpy
cimgui.lib(imgui.obj) : error LNK2001: unresolved external symbol memset

显然不再链接 Visual C 运行时,我真的不明白为什么,我可以立即添加它,但让我们退后一步并从代码中删除 Cimgui:

#include "SDL.h"
#undef main
#pragma comment(lib, "SDL2-staticd.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "imm32.lib")
#pragma comment(lib, "version.lib")

extern "C" __declspec(dllexport) void main()
{
SDL_Init(0);
}

我收到 13 个与此类似的错误:

MSVCRTD.lib(_init_.obj) : error LNK2019: unresolved external symbol _CrtDbgReport referenced in function _CRT_RTC_INIT

因此我手动包含了包含缺失符号的库:ucrtd.libvcruntimed.lib,然后 DLL 构建正常。

现在我尝试再次添加 Cimgui,但它无法构建并出现如下错误:

MSVCRTD.lib(utility.obj) : error LNK2019: unresolved external symbol __vcrt_initialize referenced in function __scrt_initialize_crt
MSVCRTD.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_initialize referenced in function __scrt_initialize_crt

__vcrt定义在libvcruntimed.lib中,而__acrt定义在libucrtd.lib中,这与 ucrtd.lib 冲突,即使我完全删除 ucrtd.lib 并尝试仅链接 libucrtd.lib,我也会收到类似这样的错误:

ucrtd.lib(ucrtbased.dll) : error LNK2005: malloc already defined in libucrtd.lib(malloc.obj)

我不知道如何解释,因为我没有链接 ucrtd.lib

我真的不明白为什么构建 DLL 不像构​​建可执行文件,特别是因为 EXE 二进制文件与 DLL 非常相似,我什至可以将它用作 DLL,但感觉不对.我确信有一种方法可以构建它,但我只是不知道如何构建。

为了完整性(以防万一),这里是 EXE 和 DLL 的链接器命令:

/OUT:"C:\Projects\BuildTest\x64\Debug\Build.dll" /MANIFEST /NXCOMPAT /PDB:"C:\Projects\BuildTest\x64\Debug\Build.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /DLL /MACHINE:X64 /INCREMENTAL /PGD:"C:\Projects\BuildTest\x64\Debug\Build.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Debug\Build.dll.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"C:\Projects\cimgui_build\Debug" /LIBPATH:"C:\Projects\SDL2-2.0.8\build\Debug" /TLBID:1 
/OUT:"C:\Projects\BuildTest\x64\Debug\Build.exe" /MANIFEST /NXCOMPAT /PDB:"C:\Projects\BuildTest\x64\Debug\Build.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X64 /INCREMENTAL /PGD:"C:\Projects\BuildTest\x64\Debug\Build.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Debug\Build.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"C:\Projects\cimgui_build\Debug" /LIBPATH:"C:\Projects\SDL2-2.0.8\build\Debug" /TLBID:1

编辑:

我做了一个“最小的、完整的和可验证的例子”(独立的——包括依赖项、相对路径、VS2017 项目,如果你有 Windows SDK 应该直接编译)并在这里在线发布:

https://bitbucket.org/AlanGameDev/buildmvce_so/downloads/

(您可以根据需要下载并提取或克隆)

最佳答案

如果您将链接器标志/VERBOSE 设置为 exe/dll 构建并比较结果,您将获得关于正在发生的事情的线索。

在 exe 构建中你会看到

1>      Found mainCRTStartup
1> Loaded MSVCRTD.lib(exe_main.obj)
...

1> Found __xi_a
1> Referenced in MSVCRTD.lib(exe_main.obj)
1> Loaded MSVCRTD.lib(initializers.obj)
1>Processed /DEFAULTLIB:kernel32.lib
1> Processed /DISALLOWLIB:msvcrt.lib
1> Processed /DISALLOWLIB:libcmt.lib
1> Processed /DISALLOWLIB:libcmtd.lib
1> Processed /DISALLOWLIB:vcruntime.lib
1>Processed /DEFAULTLIB:vcruntimed.lib
1> Processed /DISALLOWLIB:libvcruntime.lib
1> Processed /DISALLOWLIB:libvcruntimed.lib
1> Processed /DISALLOWLIB:ucrt.lib
1>Processed /DEFAULTLIB:ucrtd.lib
1> Processed /DISALLOWLIB:libucrt.lib
1> Processed /DISALLOWLIB:libucrtd.lib

没有一个出现在 dll 构建中。在 dll 构建中,您只会看到 -

1>      Found _DllMainCRTStartup
1> Loaded SDL2-staticd.lib(SDL.obj)

这很奇怪。似乎 SDL2 包含它自己的入口点 _DllMainCRTStartup 的实现,并且由于链接器从那里获取它而不是 crt 库 - 它错过了很多有用的/DEFAULTLIB 编译指示。

谷歌搜索似乎 _dllMainCRTStartup 包含在 SDL to satisfy some Watcom needs 中, 并且已经怀疑它在 MSVC 中引起了麻烦。

如果您从源代码构建 SDL,您可能应该只注释掉 _dllMainCRTStartup 实现并(希望)成功构建。

关于c++ - MSVC - 可执行文件构建正确但 DLL 不正确,缺少符号和冲突的依赖项 - SSCCE/Repro,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52684820/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com