2013-09-16 28 views
0

出于好奇,当使用MSVCR编译的应用程序加载时会发生什么, Windows的加载程序如何实际初始化CRT?对于我目前收集的内容,当程序以及所有导入的库被加载到内存中并且所有的重定位完成时,CRT启动代码(_CRT_INIT()?)初始化.CRT$XC*部分中的所有全局初始化程序,并调用用户定义的main()功能。我希望迄今为止这是正确的。我们假设,为了解释起见,不使用MSVCR的程序(例如,用Cygwin GCC或其他编译器构建的应用程序)试图在运行时加载库,需要CRT,使用自定义加载器/运行时链接程序,因此不涉及LoadLibrary()。加载器/链接器如何处理CRT初始化?是否必须手动初始化所​​述部分中的所有“对象”,是否必须执行其他操作才能使库的内部接线正常工作,还是必须调用_CRT_INIT()(在运行时本身中定义的不切实际,据我所知,没有出口到任何地方)。假设非CRT应用程序和CRT库不会传递任何对象,例外和它们之间的事情之类,这种混淆甚至会以任何方式工作吗?MSVCR和CRT初始化

我会找到出去很感兴趣,因为我不能完全让出了什么CRT对实际加载过程的影响...

的所有信息都非常感谢,谢谢!

回答

2

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

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

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

+0

好吧 - 所以基本上所有的CRT初始化都是“只是”_DllMainCRTStartup()在crtdll.c源文件中执行的所有操作幸运的是与VS发货,所以每个人都可以看看它:-))?我必须说,这比我最初想象的要少得多“魔术”,但另一方面......我还期望别的什么? ;)谢谢你的澄清! – PuerNoctis

+0

那里没有魔法,我很抱歉地解雇你。 –

2

当你了解编程知识时,有人会告诉你“发生的第一件事是代码在main中运行,但是当你在学校学习原子时,它们有点像它们组织得很好并且操作起来很顺利如果你后来去上大学的核/粒子物理课,那些简单/严格的规则就更加详细,并不总是适用,等等。

当你连接一个C或C++程序时,CRT包含如下代码:

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

所以初始化是由C运行时库本身,它调用你的主。

DLL有一个DllMain,由LoadLibrary()执行 - 它负责初始化/创建DLL中的全局对象,并且如果你不使用LoadLibrary() [例如,将DLL自动加载到内存中],那么你将不得不确保对象被创建和初始化。

3

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

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