Win32、WinMain 与自定义入口点(大小差异巨大),为什么?

Zer*_*ker 2 c winapi

正如主题所说。

我注意到,如果我使用 WinMain 或任何其他默认入口点,C 应用程序可能约为 70kb。

但如果我只是指定一个自定义入口点,比如“RawMain”,int RawMain()。那么文件大小大约是6kb。

所以我想知道为什么会这样,它添加/引用了文件什么?我可以理解尺寸上存在一些微小差异,但对于空应用程序来说差异巨大。

谢谢!

Art*_*kes 5

在大多数环境中为 Windows 构建时,实际的程序入口点将由小型运行时库中的函数提供。那会做一些环境准备,然后调用你提供的函数,比如main、wmain、WinMain等。

在用户提供的 main 函数之前运行的代码包括运行全局 C++ 构造函数、启用 TLS 变量、初始化全局互斥体以便标准库调用在多线程环境中正常工作、设置标准区域设置以及其他内容。

设置入口点所做的一件事是使用未定义的符号和您为入口点指定的名称启动链接器,因此,例如,如果您使用 mingw32,链接器将开始假设它需要链接并使用libmingw32.a未定义的符号。象征__tmainCRTStartup

链接器将(希望)__tmainCRTStartup在 中找到libmingw32.a,并包含包含它的目标文件crtexe.o,以及满足源自 的未定义符号所需的任何其他内容crtexe.o,这就是额外大小的来源。

当您设置自己的入口点时,您可以覆盖它,并且只需设置链接器来查找您指定的任何函数。您将获得较小的可执行文件,但必须小心,您使用的功能不依赖于运行时的启动函数完成的任何全局初始化。

  • 使用标准 C 语言环境函数,假设线程本地存储中定义的全局变量指向有意义的值,在多线程环境中使用标准 C 库中的 strtok。这些是我能想到的影响 Windows 上的 C 的内容。 (2认同)
  • @Zerowalker:CRT 负责的功能还有很多。此外,CRT还初始化FPU环境,实现部分SEH异常处理,并包含多字运算的代码。这个列表仍然并不详尽,但应该清楚的是,(虽然可能)编写不使用 CRT 的应用程序是一个真正的挑战。某些功能将因编译器/链接器错误而失败,但其他功能(例如,为全局对象运行初始化程序)将被静默跳过。 (2认同)