我这里有一个可运行的可执行文件,我试图用相同的代码构建DLL,但是我遇到了一些奇怪的错误,并且在尝试了很多错误后设法查明了罪魁祸首,我决定要求帮助,因为我现在真的很困。我在我的代码中同时静态链接了SDL2和Cimgui(亲爱的Imgui C包装器),可执行文件运行良好:
#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
选项,以确保链接命令中的唯一区别是{{1 }}和扩展名)。当我尝试构建时,出现关于/DLL
的错误,例如:
cimgui.lib
很明显,Visual C运行时不再链接了,我真的不明白为什么,我可以立即添加它,但让我们退后一步,从代码中删除Cimgui:
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
我得到13个与此类似的错误:
#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);
}
因此,我手动添加了包含缺少符号的库:MSVCRTD.lib(_init_.obj) : error LNK2019: unresolved external symbol _CrtDbgReport referenced in function _CRT_RTC_INIT
,ucrtd.lib
,然后DLL构建良好。
现在,我尝试再次添加Cimgui,但是由于以下错误而无法构建:
vcruntimed.lib
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
冲突,即使我删除了{{ 1}}并尝试仅链接ucrtd.lib
,我收到类似以下错误:
ucrtd.lib
我不知道该怎么解释,因为我没有链接libucrtd.lib
。
我真的不明白为什么构建DLL并不像构建可执行文件,特别是因为EXE二进制文件与DLL非常相似,我什至可以使用它作为DLL互操作,但是感觉不对。 。我敢肯定有一种方法可以构建它,而我只是不知道该怎么做。
为了完整性(以防万一),以下是EXE和DLL的链接器命令:
ucrtd.lib(ucrtbased.dll) : error LNK2005: malloc already defined in libucrtd.lib(malloc.obj)
编辑:
我制作了一个“最小,完整和可验证的示例”(自包含-包括依赖项,相对路径,VS2017项目,如果您具有Windows SDK,则应直接编译)并在此处在线发布:
https://bitbucket.org/AlanGameDev/buildmvce_so/downloads/
(您可以根据需要下载,提取或克隆)
答案 0 :(得分:0)
如果将链接器标志/ VERBOSE都设置为exe / dll构建并比较结果,则将了解发生了什么。
在exe版本中,您会看到
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="">
<table id="dyn">
<tr>
<td><input type="text" name="name[]" placeholder="Enter your Name" class="form-control name_list" /></td>
<td><button type="button" name="add" id="add" class="btn btn-success">Add More</button></td>
</tr>
</table>
<button type="button" id="submit"></button>
没有一个出现在dll版本中。在dll版本中,您只会看到-
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
这很奇怪。似乎SDL2包含了它自己的入口点_DllMainCRTStartup的实现,并且由于链接器从那里而不是crt lib那里获取它-错过了很多有用的/ DEFAULTLIB编译指示。
谷歌搜索似乎_dllMainCRTStartup包含在SDL to satisfy some Watcom needs中,并且已经怀疑它会在MSVC中引起麻烦。
如果您从源代码构建SDL,则可能应该注释掉_dllMainCRTStartup实现并(希望)成功构建。