C++ 对“WinMain@16”的未定义引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5259714/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
undefined reference to `WinMain@16'
提问by Simplicity
When I try to build a program using Eclipse CDT
, I get the following:
当我尝试使用 构建程序时Eclipse CDT
,我得到以下信息:
/mingw/lib/libmingw32.a(main.o):main.c:(.text+0x106): undefined reference to `WinMain@16
/mingw/lib/libmingw32.a(main.o):main.c:(.text+0x106):对`WinMain@16的未定义引用
Why is that? And, how can I solve this issue?
这是为什么?而且,我该如何解决这个问题?
回答by Cheers and hth. - Alf
Consider the following Windows API-level program:
考虑以下 Windows API 级程序:
#define NOMINMAX
#include <windows.h>
int main()
{
MessageBox( 0, "Blah blah...", "My Windows app!", MB_SETFOREGROUND );
}
Now let's build it using GNU toolchain (i.e. g++), no special options. Here gnuc
is just a batch file that I use for that. It only supplies options to make g++ more standard:
现在让我们使用 GNU 工具链(即 g++)构建它,没有特殊选项。这gnuc
只是我用于此目的的批处理文件。它只提供使 g++ 更加标准的选项:
C:\test> gnuc x.cpp C:\test> objdump -x a.exe | findstr /i "^subsystem" Subsystem 00000003 (Windows CUI) C:\test> _
This means that the linker by default produced a console subsystemexecutable. The subsystemvalue in the file header tells Windows what services the program requires. In this case, with console system, that the program requires a console window.
这意味着默认情况下链接器会生成一个控制台子系统可执行文件。文件头中的子系统值告诉 Windows 程序需要哪些服务。在这种情况下,使用控制台系统,该程序需要一个控制台窗口。
This also causes the command interpreter to wait for the program to complete.
这也会导致命令解释器等待程序完成。
Now let's build it with GUI subsystem, which just means that the program does not require a console window:
现在让我们用GUI 子系统来构建它,这意味着程序不需要控制台窗口:
C:\test> gnuc x.cpp -mwindows C:\test> objdump -x a.exe | findstr /i "^subsystem" Subsystem 00000002 (Windows GUI) C:\test> _
Hopefully that's OK so far, although the -mwindows
flag is just semi-documented.
希望到目前为止一切正常,尽管该-mwindows
标志只是半文档化。
Building without that semi-documented flag one would have to more specifically tell the linker which subsystem value one desires, and some Windows API import libraries will then in general have to be specified explicitly:
如果没有那个半文档化的标志,则必须更具体地告诉链接器需要哪个子系统值,然后通常必须明确指定一些 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> _
That worked fine, with the GNU toolchain.
使用 GNU 工具链,效果很好。
But what about the Microsoft toolchain, i.e. Visual C++?
但是微软的工具链,即 Visual C++ 呢?
Well, building as a console subsystem executable works fine:
好吧,构建为控制台子系统可执行文件工作正常:
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> _
However, with Microsoft's toolchain building as GUI subsystem does not work by default:
但是,默认情况下,将 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> _
Technically this is because Microsoft’s linker is non-standard by default for GUI subsystem. By default, when the subsystem is GUI, then Microsoft's linker uses a runtime library entry point, the function where the machine code execution starts, called winMainCRTStartup
, that calls Microsoft's non-standard WinMain
instead of standard main
.
从技术上讲,这是因为默认情况下,Microsoft 的链接器对于 GUI 子系统是非标准的。默认情况下,当子系统是 GUI 时,Microsoft 的链接器使用运行时库入口点,即机器代码执行开始的函数,称为winMainCRTStartup
,调用 Microsoft 的 non-standardWinMain
而不是 standard main
。
No big deal to fix that, though.
不过,解决这个问题没什么大不了的。
All you have to do is to tell Microsoft's linker which entry point to use, namely mainCRTStartup
, which calls standard main
:
你所要做的就是告诉微软的链接器使用哪个入口点,即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> _
No problem, but very tedious. And so arcane and hidden that most Windows programmers, who mostly only use Microsoft’s non-standard-by-default tools, do not even know about it, and mistakenly think that a Windows GUI subsystem program “must” have non-standard WinMain
instead of standard main
. In passing, with C++0x Microsoft will have a problem with this, since the compiler must then advertize whether it's free-standing or hosted (when hosted it must support standard main
).
没问题,但非常乏味。如此神秘和隐蔽,以至于大多数只使用 Microsoft 的非默认默认工具的 Windows 程序员甚至不知道它,并错误地认为 Windows GUI 子系统程序“必须”具有非标准WinMain
而不是标准main
. 顺便说一句,使用 C++0x 时,Microsoft 会遇到这个问题,因为编译器必须声明它是独立的还是托管的(托管时它必须支持标准main
)。
Anyway, that's the reason why g++ cancomplain about WinMain
missing: it's a silly non-standard startup function that Microsoft's tools require by default for GUI subsystem programs.
无论如何,这就是 g++可以抱怨WinMain
缺少的原因:这是一个愚蠢的非标准启动功能,Microsoft 的工具默认情况下需要用于 GUI 子系统程序。
But as you can see above, g++ has no problem with standard main
even for a GUI subsystem program.
但是正如您在上面看到的,main
即使对于 GUI 子系统程序,g++ 也没有标准问题。
So what could be the problem?
那么可能是什么问题呢?
Well, you are probably missinga main
. And you probably have no (proper) WinMain
either! And then g++, after having searched for main
(no such), and for Microsoft's non-standard WinMain
(no such), reports that the latter is missing.
好吧,您可能缺少一个main
. 你可能也没有(适当的)WinMain
!然后g ++,在搜索了main
(没有这样的)和微软的非标准WinMain
(没有这样的)之后,报告说后者丢失了。
Testing with an empty source:
使用空源进行测试:
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> _
回答by Tim Ludwinski
To summarize the above post by Cheers and hth. - Alf, Make sure you have main()
or WinMain()
defined and g++ should do the right thing.
总结 Cheers 和 hth 的上述帖子。- Alf,请确保您已经main()
或WinMain()
定义了并且 g++ 应该做正确的事情。
My problem was that main()
was defined inside of a namespace by accident.
我的问题是它main()
是在命名空间内意外定义的。
回答by X-Frox
I was encountering this error while compiling my application with SDL. This was caused by SDL defining it's own main function in SDL_main.h. To prevent SDL define the main function an SDL_MAIN_HANDLED macro has to be defined before the SDL.h header is included.
使用 SDL 编译应用程序时遇到此错误。这是由 SDL 在 SDL_main.h 中定义它自己的主要函数引起的。为了防止 SDL 定义主函数,必须在包含 SDL.h 头文件之前定义 SDL_MAIN_HANDLED 宏。
回答by JabbaJava
Try saving your .c file before building. I believe your computer is referencing a path to a file with no information inside of it.
在构建之前尝试保存您的 .c 文件。我相信您的计算机正在引用一个文件路径,其中没有任何信息。
--Had similar issue when building C projects
--在构建C项目时有类似的问题
回答by chthonicThreat
Check that All Files are Included in Your Project:
检查所有文件是否包含在您的项目中:
I had this same error pop up after I updated cLion. After hours of tinkering, I noticed one of my files was not included in the project target. After I added it back to the active project, I stopped getting the undefined reference to winmain16, and the code compiled.
更新 cLion 后,我弹出了同样的错误。经过数小时的修补,我注意到我的一个文件未包含在项目目标中。将其添加回活动项目后,我停止获取对 winmain16 的未定义引用,并编译代码。
Edit: It's also worthwhile to check the build settings within your IDE.
编辑:检查 IDE 中的构建设置也是值得的。
(Not sure if this error is related to having recently updated the IDE - could be causal or simply correlative. Feel free to comment with any insight on that factor!)
(不确定此错误是否与最近更新了 IDE 相关 - 可能是因果关系,也可能只是相关。请随意评论有关该因素的任何见解!)