【问题标题】:CRT initialization and DLLMainCRT 初始化和 DLLMain
【发布时间】:2015-02-07 14:55:46
【问题描述】:

引述:

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

“DLL 通常具有复杂的相互依赖关系,这些依赖关系隐含地定义了顺序 它们必须加载。库加载器有效地分析了这些 依赖关系,计算正确的加载顺序,并在其中加载 DLL 顺序。”[1]

"(在 DLLMain 内)使用动态 C 运行中的内存管理功能- 时间 (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)会在入口之前被调用 可执行文件的点(mainCRTStartup 或 WinMainCRTStartup),基于 [3] - _DllMainCRTStartup 调用初始化 CRT 的 _CRT_INIT,并且 mainCRTStartup 也将初始化 CRT,所以实际发生了什么 用 CRT 吗?

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

谁将实际初始化 CRT DLL?

【问题讨论】:

    标签: dll msvcrt crt


    【解决方案1】:

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

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

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

    【讨论】:

    • 简单而有说服力,您的回复很有帮助。
    • 我为这个/这个答案创建了一个后续问题:stackoverflow.com/q/48302191/321013 - 如果你愿意,可以看看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多