提问人:Simplicity 提问时间:3/10/2011 最后编辑:John DiblingSimplicity 更新时间:6/20/2021 访问量:379396
未定义对“WinMain@16”的引用
undefined reference to `WinMain@16'
问:
当我尝试使用 构建程序时,我得到以下信息:Eclipse CDT
/mingw/lib/libmingw32.a(main.o):main.c:(.text+0x106): 未定义对“WinMain@16
为什么?而且,我该如何解决这个问题?
答:
当链接器找不到函数时,会发生此错误,因此可能缺少该函数。就你而言,你可能也失踪了。WinMain
main
请考虑以下 Windows API 级程序:
#define NOMINMAX
#include <windows.h>
int main()
{
MessageBox( 0, "Blah blah...", "My Windows app!", MB_SETFOREGROUND );
}
现在让我们使用 GNU 工具链(即 g++)构建它,没有特殊选项。这只是我用于此目的的批处理文件。它只提供使 g++ 更标准的选项:gnuc
C:\test> gnuc x.cpp C:\test> objdump -x a.exe | findstr /i "^subsystem" Subsystem 00000003 (Windows CUI) C:\test> _
这意味着默认情况下,链接器会生成控制台子系统可执行文件。文件头中的子系统值告诉 Windows 程序需要哪些服务。在这种情况下,对于控制台系统,程序需要一个控制台窗口。
这也会导致命令解释器等待程序完成。
现在让我们使用 GUI 子系统构建它,这意味着程序不需要控制台窗口:
C:\test> gnuc x.cpp -mwindows C:\test> objdump -x a.exe | findstr /i "^subsystem" Subsystem 00000002 (Windows GUI) C:\test> _
希望到目前为止没问题,尽管该标志只是半记录的。-mwindows
在没有该半文档标志的情况下进行构建时,必须更具体地告诉链接器需要哪个子系统值,并且通常必须显式指定某些 Windows API 导入库:
C:\test> gnuc x.cpp -Wl,-subsystem,windows C:\test> objdump -x a.exe | findstr /i "^subsystem" Subsystem 00000002 (Windows GUI) C:\test> _
这在GNU工具链上工作得很好。
但是Microsoft工具链,即Visual C++呢?
好吧,构建为控制台子系统可执行文件工作正常:
C:\test> msvc x.cpp user32.lib x.cpp C:\test> dumpbin /headers x.exe | find /i "subsystem" | find /i "Windows" 3 subsystem (Windows CUI) C:\test> _
但是,默认情况下,将 Microsoft 的工具链构建为 GUI 子系统不起作用:
C:\test> msvc x.cpp user32.lib /link /subsystem:windows x.cpp LIBCMT.lib(wincrt0.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartu p x.exe : fatal error LNK1120: 1 unresolved externals C:\test> _
从技术上讲,这是因为 Microsoft 的链接器默认是 GUI 子系统的标准。默认情况下,当子系统是 GUI 时,Microsoft 的链接器使用运行时库入口点,即机器代码执行开始的函数,称为 ,它调用 Microsoft 的非标准 WinMain
而不是标准 。winMainCRTStartup
main
不过,解决这个问题没什么大不了的。
您所要做的就是告诉 Microsoft 的链接器使用哪个入口点,即 ,哪个调用标准:mainCRTStartup
main
C:\test> msvc x.cpp user32.lib /link /subsystem:windows /entry:mainCRTStartup x.cpp C:\test> dumpbin /headers x.exe | find /i "subsystem" | find /i "Windows" 2 subsystem (Windows GUI) C:\test> _
没问题,但很乏味。如此晦涩难懂,以至于大多数Windows程序员(大多只使用Microsoft的非标准默认工具)甚至不知道它,并错误地认为Windows GUI子系统程序“必须”具有非标准而不是标准。顺便说一下,使用 C++0x Microsoft 会遇到这个问题,因为编译器必须宣传它是独立的还是托管的(托管时它必须支持标准)。WinMain
main
main
无论如何,这就是 g++ 可以抱怨缺失的原因:这是一个愚蠢的非标准启动函数,Microsoft 的工具默认需要 GUI 子系统程序。WinMain
但正如你在上面看到的,g++ 对标准没有问题,即使对于 GUI 子系统程序也是如此。main
那么问题可能是什么呢?
好吧,您可能缺少一个.而且你可能也没有(适当的)!然后 g++,在搜索了(没有这样)和 Microsoft 的非标准(没有这样)之后,报告后者丢失了。main
WinMain
main
WinMain
使用空源进行测试:
C:\test> type nul >y.cpp C:\test> gnuc y.cpp -mwindows c:/program files/mingw/bin/../lib/gcc/mingw32/4.4.1/../../../libmingw32.a(main.o):main.c:(.text+0xd2): undefined referen ce to `WinMain@16' collect2: ld returned 1 exit status C:\test> _
评论
All you have to do is to tell Microsoft's linker which entry point to use, namely mainCRTStartup, which calls standard main
Eclipse CDT
main
WinMain
main
winmain
main
WinMain
总结一下 Cheers 和 hth 的上述帖子。- Alf,确保你已经或定义了,g++ 应该做正确的事情。main()
WinMain()
我的问题是它是偶然在命名空间中定义的。main()
评论
basic.start.main
- “它的类型应该有C++语言链接,它应该有一个声明的 int 类型的返回类型,但除此之外,它的类型是实现定义的。” - 所以如果你必须给它 C 链接,似乎有些不对劲。
我在使用 SDL 编译应用程序时遇到此错误。这是由于 SDL 在 SDL_main.h 中定义了自己的 main 函数所致。为了防止 SDL 定义 main 函数,必须在包含 SDL.h 标头之前定义一个SDL_MAIN_HANDLED宏。
评论
尝试在构建之前保存 .c 文件。我相信您的计算机正在引用一个文件路径,其中没有任何信息。
检查所有文件是否都包含在您的项目中:
更新cLion后,我弹出了同样的错误。经过几个小时的修补,我注意到我的一个文件没有包含在项目目标中。将它添加回活动项目后,我停止获取对 winmain16 的未定义引用,并且代码已编译。
编辑:检查IDE中的构建设置也是值得的。
(不确定此错误是否与最近更新的 IDE 有关 - 可能是因果关系,也可能只是相关关系。请随时对该因素发表任何见解!
我的情况是我没有主要功能。
有同样的问题。为了修复它,我单击了保存以在构建之前保存我的 .c 文件。我相信我的计算机引用了一个文件的路径,其中没有信息。
评论