未定义引用“WinMain @ 16” [英] undefined reference to `WinMain@16'

查看:1178
本文介绍了未定义引用“WinMain @ 16”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试使用 Eclipse CDT 构建程序时,我得到以下结果:

When I try to build a program using Eclipse CDT, I get the following:


/mingw/lib/libmingw32.a(main.o):main.c :(。text + 0x106):
未定义引用`WinMain @ 16

/mingw/lib/libmingw32.a(main.o):main.c:(.text+0x106): undefined reference to `WinMain@16

为什么?

推荐答案

考虑下面的Windows API级程序:

Consider the following Windows API-level program:

#define NOMINMAX
#include <windows.h>

int main()
{
    MessageBox( 0, "Blah blah...", "My Windows app!", MB_SETFOREGROUND );
}



现在让我们使用GNU toolchain(g ++)构建它,没有特殊的选项。这里 gnuc 只是一个我使用的批处理文件。它只提供使g ++更标准的选项:

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:


C:\test> gnuc x.cpp

C:\test> objdump -x a.exe | findstr /i "^subsystem"
Subsystem               00000003        (Windows CUI)

C:\test> _

这意味着默认情况下,链接器会生成控制台子系统可执行文件。文件头中的 subsystem 值告诉Windows程序需要什么服务。在这种情况下,使用控制台系统,程序需要一个控制台窗口。

This means that the linker by default produced a console subsystem executable. The subsystem value in the file header tells Windows what services the program requires. In this case, with console system, that the program requires a console window.

这也使命令解释器等待程序完成。

This also causes the command interpreter to wait for the program to complete.

现在让我们用 GUI子系统来构建它,这意味着程序不需要一个控制台窗口:

Now let's build it with GUI subsystem, which just means that the program does not require a console window:


C:\test> gnuc x.cpp -mwindows

C:\test> objdump -x a.exe | findstr /i "^subsystem"
Subsystem               00000002        (Windows GUI)

C:\test> _

希望到目前为止,虽然 -mwindows 标志只是半-documented。

Hopefully that's OK so far, although the -mwindows flag is just semi-documented.

构建没有半文档标记的人需要更具体地告诉链接器一个所期望的子系统值,然后一些Windows API导入库必须明确指定:

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:


C:\test> gnuc x.cpp -Wl,-subsystem,windows

C:\test> objdump -x a.exe | findstr /i "^subsystem"
Subsystem               00000002        (Windows GUI)

C:\test> _

用GNU工具链工作得很好。

That worked fine, with the GNU toolchain.

微软的工具链,即Visual C ++?

But what about the Microsoft toolchain, i.e. 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> _

但是,Microsoft的工具链构建作为GUI子系统默认不起作用:

However, with Microsoft's toolchain building as GUI subsystem does not work by default:


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的链接器使用运行时库入口点,即机器代码执行开始的函数, winMainCRTStartup ,调用Microsoft的非标准 WinMain 而不是标准 main

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.

没有什么大不了的解决方法。

No big deal to fix that, though.

所有你需要做的是告诉微软的链接器使用哪个入口点,即 mainCRTStartup ,它调用标准 main

All you have to do is to tell Microsoft's linker which entry point to use, namely mainCRTStartup, which calls standard 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子系统程序必须有非标准 WinMain ,而不是标准 main 。通过C ++ 0x,微软将有一个问题,因为编译器必须广告它是独立的还是托管的(当托管它必须支持标准 main )。

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).

无论如何,这就是为什么g ++ 可以抱怨 WinMain 它是一个愚蠢的非标准启动函数,微软的工具需要默认为GUI子系统程序。

Anyway, that's the reason why g++ can complain about WinMain missing: it's a silly non-standard startup function that Microsoft's tools require by default for GUI subsystem programs.

但是正如你可以看到,g ++没有问题,标准<$ c

But as you can see above, g++ has no problem with standard main even for a GUI subsystem program.

那么问题是什么呢?

好吧,你可能缺少。你可能没有(正确) WinMain !然后g ++,在搜索 main (没有这样)和微软的非标准 WinMain )。

Well, you are probably missing a 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.

使用空源进行测试:


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> _

这篇关于未定义引用“WinMain @ 16”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆