c++ - 未定义对 `WinMain@16' 的引用

标签 c++ eclipse eclipse-cdt

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

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

这是为什么呢?还有,我该如何解决这个问题?

最佳答案

当链接器找不到 WinMain 函数时,就会发生此错误,因此它可能丢失。就您而言,您可能也缺少 main

考虑以下 Windows API 级程序:

#define NOMINMAX
#include <windows.h>

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

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

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 的链接器使用运行时库入口点,即机器代码执行开始的函数,称为 winMainCRTStartup,它调用 Microsoft 的非标准 WinMain 而不是标准 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 子系统程序“必须”具有非标准 WinMain 而不是标准的 main。顺便说一句,对于 C++0x,微软会遇到这个问题,因为编译器必须通告它是独立的还是托管的(托管时它必须支持标准 main)。

无论如何,这就是 g++ 提示 WinMain 缺失的原因:这是一个愚蠢的非标准启动函数,Microsoft 的工具默认需要 GUI 子系统程序。

但正如您在上面所看到的,即使对于 GUI 子系统程序,g++ 对于标准 main 也没有问题。

那么可能是什么问题呢?

嗯,您可能缺少一个main。而且您可能也没有(正确的)WinMain!然后,g++ 在搜索了 main (没有这样的)和 Microsoft 的非标准 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> _

关于c++ - 未定义对 `WinMain@16' 的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44496020/

相关文章:

c++ - 析构函数总是命中 Null

eclipse - 如何导出 eclipse rcp 产品而不将依赖项打包到插件文件夹中

java - 导入语句的 Checkstyle 长度检查

c++ - Eclipse CDT 调试配置存储在哪里?

eclipse - 在 eclipse 中创建 java/c++ 项目

c++ - 测试 QQuickView (QWindow) 在 Qt 5.0.x 中是否全屏

c++ - 我可以用 cout 而不是迭代器循环来打印 STL 映射吗

c++ - 关于 CMake 错误 : No source given to target 的问题

c++ - 检测单元测试中的特定函数调用

Eclipse IDE 上次编辑位置历史记录 - 后退多个步骤?