gpt4 book ai didi

c++ - DllGetClassObject是在C++静态初始化之前还是之后调用

转载 作者:行者123 更新时间:2023-11-30 04:51:49 25 4
gpt4 key购买 nike

我有一个加载到 Microsoft 管理控制台 (MMC) 中的 DLL。看起来它的DllGetClassObject 函数正在调用第三方库的一些初始化函数,这些函数已知依赖于静态初始化才能完成(所以它不能在main()< 之前被调用 在常规 C++ 程序中)。此功能似乎失败,管理单元未显示在 MMC 中。奇怪的是,如果我将它从 MMC 中删除并再次添加,它会成功加载。

关于 DLL 中 C++ 静态初始化发生的确切时间(在回调之前和之后)的信息似乎很少,并且 Microsoft 似乎已经删除了它的“DLL 最佳实践”论文,许多答案和处理这类问题。

是否有关于 C++ 静态初始化和 DLL 回调顺序的权威信息(最好是在 MSDN 上)?

(我已经尝试过 https://learn.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-dllgetclassobject ,我希望它被记录在案)

编辑:将有问题的函数调用从 DllGetClassObject 移动到 DllMain 似乎可以解决问题。不过,仍在寻找权威文档。

编辑:从这个结果和答案得出结论,我在第三方初始化函数中遇到的问题不可能是由静态初始化引起的,因为静态初始化应该在 DllMain 之前完成,并且因此也在 DllGetClassObject 之前。

最佳答案

在不宽恕或避免在 DLL 中使用 C++ 对象作为全局变量/静态变量的情况下,这里是您正在寻找的信息。操作顺序是:

  1. C/C++ 全局/静态初始化
  2. DllMain
  3. DllGetClassObject

文档 here描述了 C/C++ 全局/静态初始化和 DllMain 之间的关系。

...When linked into a DLL, the VCRuntime code provides an internal DLL entry-point function called _DllMainCRTStartup that handles Windows OS messages to the DLL to attach to or detach from a process or thread. The _DllMainCRTStartup function performs essential tasks such as stack buffer security set up, C run-time library (CRT) initialization and termination, and calls to constructors and destructors for static and global objects. _DllMainCRTStartup also calls hook functions for other libraries such as WinRT, MFC, and ATL to perform their own initialization and termination. Without this initialization, the CRT and other libraries, as well as your static variables, would be left in an uninitialized state...

...On process attach, the _DllMainCRTStartup function sets up buffer security checks, initializes the CRT and other libraries, initializes run-time type information, initializes and calls constructors for static and non-local data, initializes thread-local storage, increments an internal static counter for each attach, and then calls a user- or library-supplied DllMain...

您可以通过在 DllMain 中设置断点然后查看导致调用 DllMain 的堆栈帧来自己查看所有这些内容。您会发现甚至在调用 DllMain 之前就已经完成了很多有趣的事情。

至于DllGetClassObject:这个导出的函数不是被魔法调用的。此函数的调用者必须做 3 件事 - 加载您的 DLL(例如,LoadLibrary),查找从 DLL 加载的函数的地址(例如,GetProcAddress) ,然后使用为 DllGetClassObject 实现已知的签名调用该地址。您可以手动执行所有这些操作,但 CoCreateInstance 等函数会按照此处描述的顺序自动执行这三项操作。 DllMain在调用LoadLibrary时自动调用,LoadLibrary直到DllMain返回后才返回。如果 DllMain 返回成功代码,则 LoadLibrary 的调用方将收到 DLL 的 HMODULE。如果 DllMain 返回错误代码,调用者永远不会有 DLL 的 HMODULE(LoadLibrary 将返回 NULL ),因此调用者甚至无法找到您的 DllGetClassObject 函数,更不用说调用它了。

关于c++ - DllGetClassObject是在C++静态初始化之前还是之后调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54705714/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com