这是另一个关于臭名昭著的tmainCRTStartup未解析外部符号的线程。是的,这又是关于SDL的,但它有一个转折点,AFAICS还没有在这里涵盖。
首先让我澄清一些参数:
1)我试图构建一个静态链接到SDL2.lib的DLL。
2)我使用的不是Visual Studio,而是Visual C和控制台(先是cmake,然后是nmake)。
3)项目完全在C中,没有C++代码在那里(除非在SDL2中有C++,但AFIK SDL2完全在C中)
4)SDL2.lib中收集的所有对象和其他对象都是使用/MT编译的,也就是说,我希望与Visual C运行时(libcmt.lib)进行静态链接。
5)然后创建SDL2.lib,如下所示:

link /nologo /lib /out:SDL2.lib file1.obj file2.obj....

6)目标DLL的链接方式如下:
link /dll /subsystem:WINDOWS /out:test.dll file1.obj file2.obj ... kernel32.lib user32.lib gdi32.lib shell32.lib ole32.lib oleaut32.lib imm32.lib winmm.lib version.lib SDL2.lib

让我困惑的是,上面的调用会产生以下错误:
LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup

这怎么可能发生?我很清楚地将/dll传递给link.exe,那么为什么C运行时要查找main()?它应该在找DllMain()!DLL中的main()符号一点意义都没有,但我得到了这个令人困惑的错误!
引起这个问题的一定是SDL2.lib中的某个东西,但我真的不知道是什么能迫使链接器在这里寻找main()入口点。我的意思是,SDL2.lib是一个链接器库,它应该是完全目标中立的,即它应该可以链接SDL2.lib到WinMain()可执行文件,但它也应该可以链接SDL2.lib到DllMain()库,但这里似乎拒绝链接到DLL!
有人知道这里有什么问题吗?我已经找了好几个小时了,这件事让我完全忘记了。
编辑:有趣的是,当所有的东西都使用/MD编译时,这个问题不会出现。它只在使用/MT时出现。我真的完全不知道这里的原因是什么。
EDIT2:我也试过用/DSDL_MAIN_处理来编译SDL2,但这并没有消除错误。

最佳答案

差不多四年后,我终于重温了这个问题,在查看了所有对象文件以确定哪一个是罪魁祸首之后,我终于在src/SDL.c中找到了错误它的结尾有以下几行:

#if defined(__WIN32__)

#if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL))
/* Need to include DllMain() on Watcom C for some reason.. */

BOOL APIENTRY
_DllMainCRTStartup(HANDLE hModule,
                   DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
#endif /* building DLL with Watcom C */

#endif /* __WIN32__ */

因此,SDL总是定义一个_DllMainCRTStartup符号,这似乎混淆了链接器并导致了操作中显示的错误。终止上面的代码(或定义HAVE_LIBC)最终解决了问题,我可以用/MT来构建SDL2(尽管我仍然不知道为什么用/MD编译不会导致任何问题,因为在使用_DllMainCRTStartup编译,但在这种情况下似乎不会造成任何伤害)。
问题终于解决了。

关于c - LNK2019:函数___tmainCRTStartup中使用DLL引用的未解析的外部符号_main,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25067151/

10-15 04:40