CRT初始化和DLLMain

时间:2014-12-09 16:13:54

标签: dll msvcrt crt

行情:

来自文档"创建DLL的最佳实践" Microsoft http://download.microsoft.com/download/a/f/7/af7777e5-7dcd-4800-8a0a-b18336565f5b/DLL_bestprac.doc

" DLL通常具有复杂的相互依赖性,隐含地定义了顺序 他们必须加载。库加载器有效地分析了这些 依赖项,计算正确的加载顺序,并加载DLL 为了"的 [1]

"(在DLLMain中)使用动态C Run中的内存管理功能 - 时间(CRT)。如果未初始化CRT DLL,则可以调用这些函数 导致进程崩溃。" [2]

来自MSDN:http://msdn.microsoft.com/en-us/library/988ye33t.aspx

" _DllMainCRTStartup函数执行多项操作,包括调用 _CRT_INIT,初始化C / C ++运行时库并调用C ++ 静态,非局部变量的构造函数。没有这个功能,运行 - 时间库将处于未初始化状态。" [3]

"除了初始化C运行时库之外,_DllMainCRTStartup还调用了 称为DllMain的函数。" [4]

问题:

如果您的DLL依赖于CRT DLL,基于 [1] ,CRT DLL将是 首先加载(首先初始化),那么 [2] 如何发生?

根据 [3] [4] ,_DllMainCRTStartup会调用_CRT_INIT 初始化CRT,那么 [2] 如何发生?

如果一个可执行文件通过"隐式链接"加载你的DLL,那么 在输入之前将调用DLL的_DllMainCRTStartup(和DLLMain) 基于的可执行文件的point(mainCRTStartup或WinMainCRTStartup) [3] - _DllMainCRTStartup调用_CRT_INIT初始化CRT, mainCRTStartup也将初始化CRT,所以实际发生了什么 与CRT?

如果您的DLL将在mainCRTStartup之前加载,则调用CRT函数 在DLLMain或其他导出函数中是否安全?

谁会实际初始化CRT DLL?

1 个答案:

答案 0 :(得分:8)

您的假设是DLL的入口点始终为_DllMainCRTStartup。情况并非如此,它只是链接器的默认值。它可以是程序员想要的任何东西,使用链接器的/ ENTRYPOINT选项可以快速轻松地更改。微软没有办法阻止这一点。不是一个很好的做法,指出这是该文件的重点。

因此,如果这样的自定义入口点也不能确保显式初始化CRT,则很容易调用[2]事故。这不仅涉及初始化CRT运行时状态,还涉及初始化DLL的全局状态,如调用C初始化器,静态C ++对象的构造函数和分配线程局部变量。 CRT的DLL版本无法做到的东西。请记住_DllMainCRTStartup和_CRT_INIT链接到DLL本身,该代码不在CRT的DLL版本中。

动态CRT自己的运行时状态由CRT DLL自己的入口点初始化,Windows加载器确保它首先运行。