LNK2019:函数___tmainCRTStartup中使用DLL引用了未解析的外部符号_main

时间:2014-07-31 19:15:34

标签: c winapi dll sdl

所以这是关于臭名昭着的___tmainCRTStartup未解决的外部符号的另一个线程。是的,它又是关于SDL的,但它有一个扭曲,AFAICS尚未涵盖在这里。 我先来清楚一些参数:

1)我正在尝试构建一个静态链接SDL2.lib的DLL。

2)我没有使用Visual Studio,而是使用Visual C和控制台(首先是cmake,然后是nmake)。

3)项目完全在C中,没有C ++代码(除非SDL2中有C ++,但AFAIK 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_HANDLED编译SDL2,但它不会使错误消失。

1 个答案:

答案 0 :(得分:1)

差不多四年后,我终于重新审视了这个问题,经过所有目标文件,看看哪一个是罪魁祸首,我终于在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符号,这似乎混淆了链接器并导致OP中显示的错误。杀死上面的代码(或定义HAVE_LIBC)最终解决了问题,我可以使用/MT构建SDL2(虽然我仍然不知道为什么用/MD编译并没有&# 39;引起任何问题,因为在使用_DllMainCRTStartup进行编译时也会定义AFAICS /MD,但在这种情况下它似乎不会造成任何伤害。)

问题终于解决了。