I have a working executable here and I'm trying to build a DLL from the same code, but I'm having some strange errors and managed to pinpoint the culprits after a lot of trial an error, I decided to ask for help because I'm really stuck now. I'm linking both SDL2 and Cimgui (Dear Imgui C Wrapper) statically in my code, the executable works perfectly fine:
#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");
}
So now I switch the project to DLL (I disabled that /IMPLIB
option to make sure the only difference in the link command is the /DLL
and the extension). When I try to build I get errors regarding cimgui.lib
like:
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
Apparently the Visual C runtime isn't being linked anymore, I don't really understand why, I could just add it immediately but let's step back and remove Cimgui from the code:
#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);
}
I get 13 errors similar to this:
MSVCRTD.lib(_init_.obj) : error LNK2019: unresolved external symbol _CrtDbgReport referenced in function _CRT_RTC_INIT
So I manually include the libs that contain the missing symbols: ucrtd.lib
, vcruntimed.lib
, and then the DLL builds fine.
Now I try to add Cimgui again, but it fails to build with errors like these:
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
the __vcrt
definitions are in libvcruntimed.lib
, but the __acrt
definitions are in libucrtd.lib
, which conflicts with ucrtd.lib
, and even if I remove ucrtd.lib
altogether and try to link just libucrtd.lib
, I get errors like:
ucrtd.lib(ucrtbased.dll) : error LNK2005: malloc already defined in libucrtd.lib(malloc.obj)
Which I don't know how to interpret because I'm not linking ucrtd.lib
.
I don't really understand why building a DLL isn't just like building an Executable especially because the EXE binary is very similar to the DLL and I could even use it to interop as a DLL but that doesn't feel right. I'm sure there's a way to build this and I just don't know how.
For completeness (and just in case), here are the linker commands for the EXE and 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
EDIT:
I made a "Minimal, Complete and Verifiable Example" (Self-contained - dependencies included, relative paths, VS2017 project, should compile directly provided you have Windows SDK) and published online here:
https://bitbucket.org/AlanGameDev/buildmvce_so/downloads/
(you can download and extract or clone if you prefer)