DllMain()和全局静态对象构造函数中哪个先被调用?

16

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

在对象的构造函数中,我正在进行一些可能成功或可能失败的初始化。

在DllMain()函数中,是否可以发出初始化过程的成功或失败信号?这两个函数中哪一个会首先被调用?

谢谢。

1个回答

29

MSDN的DllMain文档中写道:

如果您的DLL是与C运行时库(CRT)链接的,则CRT提供的入口点将调用全局和静态C++对象的构造函数和析构函数。因此,对于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,...) 之后销毁的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接