【发布时间】:2014-09-23 21:14:38
【问题描述】:
这是另一个关于臭名昭著的 ___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,但它不会使错误消失。
【问题讨论】:
-
如果您尝试从 SDL2 创建静态库,我认为您需要使用 lib.exe 而不是 link.exe。
-
抱歉,打错字了...我使用的是带有 /lib 选项的链接。现在已更正。我也测试过直接使用 lib.exe,但它没有任何区别。
-
SDL 有太多的手脚,这是使它在许多操作系统上可移植的必要条件。您可能正在与 src/main/windows/SDL_windows_main.c 作斗争,目的是欺骗链接器,使其相信本机 Windows 程序的入口点是 main()。当阳光普照并且你的背上有风时,这很有效。使用 /MT 编译肯定会遇到非常困难的逆风。使用项目的邮件列表,这是与 Sam Lantinga 取得联系的唯一途径。
-
你可以尝试定义一个虚拟的 main() 看看会发生什么。 :-)
-
@HansPassant:SDL_windows_main.c 不应该是罪魁祸首,因为它默认编译成一个名为 SDL2main.lib 的小型独立链接库。因为我没有链接到这个库,所以 SDL_windows_main.c 不能真正搞砸任何事情。