-->

哪些功能不_WinMainCRTStartup执行?(What functions does _Wi

2019-08-19 19:03发布

这是一个系列的至少两个密切相关的,但不同的问题的一部分。 我希望我被分别要求他们做正确的事。

我试图让我的Visual C ++ 2008的应用程序,而无需C运行时库工作。 它没有MFC或其他花哨的东西一个Win32 GUI应用程序,只是普通的Windows API。

所以我设置项目属性- >配置- > C / C ++ - >高级- >省略默认的库名称为Yes(编译器标志/Zl )和重建。

然后链接器抱怨无法解析的外部_WinMainCRTStartup 。 很公平,我可以告诉链接使用不同的切入点,说MyStartup 。 从我所收集各地的网络, _WinMainCRTStartup做一些初始化的东西,我可能想MyStartup做的一个子集。

所以我的问题是: 什么样的功能呢_WinMainCRTStartup执行,以及这些我可以省略,如果我不使用CRT?

如果你非常了解这个东西,请看看我的其他问题了。 谢谢!

旁白:为什么我想这样做摆在首位?

  1. 我的应用程序并没有明确使用任何CRT功能。
  2. 我喜欢精益和平均的应用程序。
  3. 它会教我一些新的东西。

Answer 1:

CRT的入口点执行以下(此列表不完整):

  • 初始化由CRT所需的全局状态。 如果不这样做,你不能使用由CRT提供的任何功能或状态。
  • 初始化是由编译器使用一些全局状态。 运行时检查,如通过/ GS使用的安全Cookie肯定在这里脱颖而出。 您可以拨打__security_init_cookie但是自己。 您可能需要添加其他代码为其他运行时检查。
  • 调用C ++对象构造函数。 如果你正在编写C ++代码,你可能需要仿效这一点。
  • 检索命令行并启动OS所提供的信息并传送你的主。 默认情况下,没有参数传递给由OS入口点的程序 - 它们是由CRT所有provied。

CRT的源代码可以使用Visual Studio,您可以通过CRT的入口点的调试步骤,并找出它到底是什么做的。



Answer 2:

用C写的(不是C ++) 真正的Win32程序无需任何初始化所有,这样你就可以开始与WinMainCRTStartup(项目),而不是的WinMain(HINSTANCE,...)。

也有可能,但有点难写控制台程序是真正的Win32应用程序; 入口点的默认名称为_mainCRTStartup()。

禁用所有额外的代码生成的功能,如堆叠的探针,阵列检查等调试仍然是可能的。

初始化

有时你需要第一个HINSTANCE参数。 对于Win32(除Win32s中),它被固定到(HINSTANCE)为0x400000。

该参数的nCmdShow总是SW_SHOWDEFAULT。

如果有必要,检索与GetCommandLine命令行()。

终止

当你的程序生成线程,例如通过调用GetOpenFileName(),WinMainCRTStartup()return关键字返回时,将挂在你的程序-使用了ExitProcess()来代替。

注意事项

你会遇到相当大的麻烦时:

  • 使用堆栈帧(即局部变量)大于4千字节(每个功能)
  • 使用浮点运算(例如浮子> INT转换)
  • 使用在32位机器(乘法,比特移位操作)64位整数
  • 用C ++ 新建删除 ,并与非零出所有成员构造静态对象
  • 使用标准的库函数等fopen()函数 ,当然printf()的

疑难解答

目前在所有的Windows系统(自Windows 95)可用C标准库中,MSVCRT.DLL。

要使用它,用我的msvcrt-light.lib(谷歌它)导入他们的切入点,如。 但仍有一些注意事项,使用编译器版本高于MSVC6尤其是当:

  • 栈帧仍仅限于4千字节
  • _ftol_sse_ftol2_sse必须路由到_ftol
  • _iob_func必须路由到_iob

其初始化似乎在加载时运行。 至少该文件功能将无缝运行。



Answer 3:

老问题,但答案是无论是在一个特定的问题或不正确对焦。

有许多的C和C ++的功能,根本不会有适用于Windows(或大多数操作系统,对于这个问题),如果项目实际上是在主/ WinMain函数开始。

就拿这个简单的例子:

class my_class
{
public:
    my_class() { m_val = 5; }
    int my_func(){ return m_val }
private:
    int m_val;
}

my_class g_class;

int main(int argc, char **argv)
{
     return g_class.my_func();
}

为了按预期这项计划发挥作用,为my_class构造函数必须在主被调用。 如果程序在主开始确切地说,它需要一个编译器的黑客(注:GCC做这在某些情况下)插入在主最开始的函数调用。 相反,在大多数操作系统,在大多数情况下,不同的功能构建g_class,然后调用主(在Windows上,这或者是mainCRTStartup或WinMainCRTStartup;在大多数其他操作系统,我习惯了一个名为_start功能)。

还有其他的事情C ++,甚至ç需要对之前完成或之后的主要工作。 如何stdin和stdout(给std :: cin和std ::法院)可用,一旦主开始? 如何atexit对工作的?

C标准要求的标准库有一个类POSIX API信号之前,其主要在Windows上必须“安装”()。

在大多数操作系统,也没有系统提供的堆; C运行时实现自己的堆(微软的C运行时只是包装了的Kernel32堆函数)。

即使传递给主,argc和argv参数,必须从系统以某种方式得到。

你可能想看看关于实施自己的C运行时的细节马特Pietrick的(古)的文章如何与Windows + MSVC(注:MinGW和Cygwin的实施具体的不同的事情,但实际上回落到MSVCRT对大多数事情): http://msdn.microsoft.com/en-us/library/bb985746.aspx



文章来源: What functions does _WinMainCRTStartup perform?