0

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

But let's assume, for the sake of explanation, a program that is not using the MSVCR (e.g. an application built with Cygwin GCC or other compilers) tries to load a library at runtime, requiring the CRT, using a custom loader/runtime linker, so no LoadLibrary() involved. How would the loader/linker has to handle CRT initialization? Would it have to manually initialize all "objects" in said sections, does it have to do something else to make the internal wiring of the library work properly, or would it have to just call _CRT_INIT() (which unpractically is defined in the runtime itself and not exported anywhere as far as I am aware). Would this mix-up even work in any way, assuming that the non-CRT application and the CRT-library would not pass any objects, exceptions and things the like between them?

我很想知道,因为我不太清楚 CRT 对实际加载过程有什么影响......

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

4

3 回答 3

3

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

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

于 2013-09-16T19:02:11.453 回答
2

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

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

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

于 2013-09-16T18:58:43.463 回答
2

当你学习编程时,有人会告诉你“首先发生的事情是代码运行在main.你后来去了大学的核/粒子物理课,那些简单/严格的规则要详细得多,并不总是适用,等等。

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

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

所以初始化是由 C 运行时库本身完成的,在它调用你的 main.

一个 DLL 有一个DllMain执行者LoadLibrary()——它负责在 DLL 中初始化/创建全局对象,如果您不使用LoadLibrary()[例如,自己将 DLL 加载到内存中],那么您必须确保创建和初始化对象.

于 2013-09-16T19:00:51.863 回答