【问题标题】:Which is called first, DllMain() or global static object constructor?首先调用的是 DllMain() 还是全局静态对象构造函数?
【发布时间】:2011-05-28 15:06:36
【问题描述】:

我正在编写一个定义全局静态对象的 DLL。

在对象的构造函数中,我正在做一些可能会或可能不会成功的初始化。

是否可以在 DllMain() 中指示初始化过程的成功或失败?两者中哪个先调用?

谢谢。

【问题讨论】:

    标签: dll object static constructor global-variables


    【解决方案1】:

    MSDN 的 DllMain 文档说:

    如果您的 DLL 与 C 链接 运行时库 (CRT),条目 CRT 提供的点调用 构造函数和析构函数 全局和静态 C++ 对象。 因此,这些限制对于 DllMain 也适用于构造函数和 析构函数和任何代码 从他们那里打电话。

    由于 DllMain 中的代码可能会使用静态对象,因此静态对象必须在 DllMain 运行前为 DLL_PROCESS_ATTACH 构建,并在运行后销毁 DLL_PROCESS_DETACH。

    您可以使用简单的测试 exe 和测试 dll 来验证这一点。

    EXE:

    int _tmain(int argc, _TCHAR* argv[])
    {
        wprintf(L"Main, loading library\n");
        HMODULE h = LoadLibrary(L"Test.dll");
    
        if (h)
        {
            wprintf(L"Main, freeing library\n");
            FreeLibrary(h);
        }
    
        wprintf(L"Main, exiting\n");
        return 0;
    }
    

    DLL:

    struct Moo
    {
        Moo() { wprintf(L"Moo, constructor\n"); }
        ~Moo() { wprintf(L"Moo, destructor\n"); }
    };
    
    Moo m;
    
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved)
    {
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
            wprintf(L"DllMain, DLL_PROCESS_ATTACH\n");
            break;
        case DLL_THREAD_ATTACH:
            wprintf(L"DllMain, DLL_THREAD_ATTACH\n");
            break;
        case DLL_THREAD_DETACH:
            wprintf(L"DllMain, DLL_THREAD_DETACH\n");
            break;
        case DLL_PROCESS_DETACH:
            wprintf(L"DllMain, DLL_PROCESS_DETACH\n");
            break;
        default:
            wprintf(L"DllMain, ????\n");
            break;
        }
        return TRUE;
    }
    

    这些将一起打印:

    Main, loading library
    Moo, constructor
    DllMain, DLL_PROCESS_ATTACH
    Main, freeing library
    DllMain, DLL_PROCESS_DETACH
    Moo, destructor
    Main, exiting
    

    可以看到,静态对象在DllMain(...,DLL_PROCESS_ATTACH,...)之前构造,在DllMain(...,DLL_PROCESS_DETACH,...)之后销毁

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-06
      • 1970-01-01
      • 1970-01-01
      • 2018-08-11
      相关资源
      最近更新 更多