【发布时间】:2021-11-18 23:54:20
【问题描述】:
当我尝试使用Eclipse CDT 构建程序时,我得到以下信息:
/mingw/lib/libmingw32.a(main.o):main.c:(.text+0x106): 未定义对 `WinMain@16
的引用
这是为什么呢?还有,我该如何解决这个问题?
【问题讨论】:
-
尝试保存您的文件并在我的情况下重新运行它成功了
标签: c++ eclipse eclipse-cdt
当我尝试使用Eclipse CDT 构建程序时,我得到以下信息:
/mingw/lib/libmingw32.a(main.o):main.c:(.text+0x106): 未定义对 `WinMain@16
的引用
这是为什么呢?还有,我该如何解决这个问题?
【问题讨论】:
标签: c++ eclipse eclipse-cdt
当链接器找不到WinMain 函数时会发生此错误,因此它可能丢失了。在您的情况下,您可能也缺少main。
考虑以下 Windows API 级程序:
#define NOMINMAX
#include <windows.h>
int main()
{
MessageBox( 0, "Blah blah...", "My Windows app!", MB_SETFOREGROUND );
}
现在让我们使用 GNU 工具链(即 g++)构建它,没有特殊选项。这里gnuc 只是我使用的一个批处理文件。它只提供使 g++ 更标准的选项:
这意味着链接器默认生成一个控制台子系统可执行文件。文件头中的 subsystem 值告诉 Windows 程序需要哪些服务。在这种情况下,使用控制台系统,该程序需要一个控制台窗口。
这也会导致命令解释器等待程序完成。
现在让我们用GUI子系统构建它,这只是意味着程序不需要控制台窗口:
C:\test> gnuc x.cpp -mwindows C:\test> objdump -x a.exe | findstr /i "^子系统" 子系统 00000002 (Windows GUI) C:\测试> _希望到目前为止一切正常,尽管 -mwindows 标志只是半记录的。
在没有半文档化标志的情况下构建时,必须更具体地告诉链接器需要哪个子系统值,然后通常必须明确指定一些 Windows API 导入库:
C:\test> gnuc x.cpp -Wl,-subsystem,windows C:\test> objdump -x a.exe | findstr /i "^子系统" 子系统 00000002 (Windows GUI) C:\测试> _使用 GNU 工具链效果很好。
但是 Microsoft 工具链(即 Visual C++)呢?
好吧,构建为控制台子系统可执行文件可以正常工作:
C:\test> msvc x.cpp user32.lib x.cpp C:\test> dumpbin /headers x.exe |查找 /i "子系统" |查找 /i "Windows" 3 子系统 (Windows CUI) C:\测试> _然而,微软将工具链构建为 GUI 子系统默认情况下不起作用:
C:\test> msvc x.cpp user32.lib /link /subsystem:windows x.cpp LIBCMT.lib(wincrt0.obj):错误 LNK2019:未解析的外部符号 _WinMain@16 在函数 ___tmainCRTStartu 中引用 p x.exe : 致命错误 LNK1120: 1 unresolved externals C:\测试> _从技术上讲,这是因为微软的链接器默认情况下对于 GUI 子系统是非标准的。默认情况下,当子系统为GUI时,微软的链接器使用运行时库入口点,机器代码执行开始的函数,称为winMainCRTStartup,它调用微软的非标准@ 987654327@ 而不是标准的main。
不过,解决这个问题没什么大不了的。
你所要做的就是告诉微软的链接器使用哪个入口点,即mainCRTStartup,它调用标准的main:
没问题,但是很乏味。如此神秘和隐藏,以至于大多数只使用微软默认的非标准工具的大多数 Windows 程序员甚至都不知道它,并错误地认为 Windows GUI 子系统程序“必须”具有非标准 WinMain而不是标准的main。顺便说一句,对于 C++0x,Microsoft 会遇到这个问题,因为编译器必须宣传它是独立的还是托管的(托管时它必须支持标准 main)。
无论如何,这就是为什么 g++可以抱怨WinMain 缺失的原因:这是一个愚蠢的非标准启动功能,微软的工具默认需要 GUI 子系统程序。
但正如您在上面看到的,g++ 对标准main 没有问题,即使对于 GUI 子系统程序也是如此。
那么可能是什么问题?
好吧,您可能缺少main。而且您可能也没有(正确的)WinMain!然后 g++ 在搜索了main(没有这个)和微软的非标准WinMain(没有这个)之后,报告说后者丢失了。
使用空源进行测试:
C:\test> 键入 nul >y.cpp C:\test> gnuc y.cpp -mwindows c:/程序文件/mingw/bin/../lib/gcc/mingw32/4.4.1/../../../libmingw32.a(main.o):main.c:(.text+0xd2 ): 未定义的引用 ce 到 `WinMain@16' collect2: ld 返回 1 个退出状态 C:\测试> _【讨论】:
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 是什么意思?谢谢
总结一下 Cheers and hth 的上述帖子。 - Alf,确保你定义了 main() 或 WinMain() 并且 g++ 应该做正确的事情。
我的问题是 main() 是偶然在命名空间内定义的。
【讨论】:
我在使用 SDL 编译我的应用程序时遇到了这个错误。这是由 SDL 在 SDL_main.h 中定义它自己的 main 函数引起的。为了防止 SDL 定义 main 函数,必须在包含 SDL.h 标头之前定义 SDL_MAIN_HANDLED 宏。
【讨论】:
尝试在构建之前保存您的 .c 文件。我相信您的计算机正在引用一个文件的路径,其中没有任何信息。
【讨论】:
检查您的项目中是否包含所有文件:
我在更新 cLion 后弹出了同样的错误。经过数小时的修补,我注意到我的一个文件未包含在项目目标中。将其添加回活动项目后,我停止获取对 winmain16 的未定义引用,并且代码已编译。
编辑:检查 IDE 中的构建设置也是值得的。
(不确定此错误是否与最近更新了 IDE 有关 - 可能是因果关系或只是相关的。请随时评论有关该因素的任何见解!)
【讨论】:
我的情况是我没有main函数。
【讨论】:
有同样的问题。为了修复它,我在构建之前单击了保存以保存我的 .c 文件。我相信我的计算机引用了一个文件的路径,其中没有任何信息。
【讨论】: