MSVCR和CRT初始化

时间:2013-09-16 18:31:03

标签: c++ windows crt

出于好奇,加载了使用MSVCR编译的应用程序时会发生什么。 Windows的加载程序如何实际初始化CRT?对于我到目前为止收集的内容,当程序以及所有导入的库加载到内存中并完成所有重定位时,CRT启动代码(_CRT_INIT()?)初始化{{1}中的所有全局初始值设定项} section并调用用户定义的.CRT$XC*函数。我希望到目前为止这是正确的。

但我们假设,为了便于解释,不使用MSVCR的程序(例如,使用Cygwin GCC或其他编译器构建的应用程序)尝试在运行时加载库,需要CRT,使用自定义加载器/运行时链接程序,因此不涉及main()。加载器/链接器如何处理CRT初始化?它是否必须手动初始化所​​述部分中的所有“对象”,是否必须执行其他操作才能使库的内部布线正常工作,或者是否必须只调用LoadLibrary()(不明确地定义在运行时本身,据我所知,不会导出到任何地方)。假设非CRT应用程序和CRT库不会传递它们之间的任何对象,异常和类似内容,这种混合是否会以任何方式工作?

我很想知道,因为我无法弄清楚CRT对实际装载过程有什么影响......

非常感谢任何信息,谢谢!

3 个答案:

答案 0 :(得分:3)

使用/ ENTRY链接器选项选择可执行映像的入口点。它使用的默认值在MSDN Library article中很好地记录。它们是CRT入口点。

如果要替换CRT,请选择相同的名称,或在链接时显式使用/ ENTRY选项。您还需要/ NODEFAULTLIB来阻止它链接常规.lib

答案 1 :(得分:2)

针对C ++运行时编译的每个库在加载时都调用_DllMainCRTStartup。 _DllMainCRTStartup调用_CRT_INIT,它初始化C / C ++运行时库并在静态非局部变量上调用C ++构造函数。

PE格式包含一个可选标头,该标头有一个名为“addressofentrypoint”的插槽,此插槽调用一个函数,该函数将调用_DllMainCRTStartup来触发初始化链。

在_DllMainCRTStartup完成初始化阶段后,它将调用您自己实现的DllMain()函数。

答案 2 :(得分:2)

当你学习编程时,有人会告诉你“发生的第一件事是代码在main中运行。但这有点像你在学校学习原子时,它们组织得相当好如果你以后去大学的核/粒子物理课,这些简单/严格的规则要详细得多,并不总是适用,等等。

当您链接C或C ++程序时,CRT包含一些类似的代码:

start()
{
   CRT_init();
   ...
   Global_Object_Constructors(); 
   ... 
   exit(main());
}

因此初始化由C运行时库本身完成,在它调用main之前。

DLL有一个由DllMain执行的LoadLibrary() - 它负责初始化/创建DLL中的全局对象,如果你不使用LoadLibrary() [例如}自己将DLL加载到内存中]然后你必须确保创建和初始化对象。