首先调用DllMain()或全局静态对象构造函数?

War*_*tin 14 dll static constructor global-variables object

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

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

是否有可能在DllMain()中表示初始化过程的成功或失败?首先叫哪两个?

谢谢.

Leo*_*son 26

MSDN的DllMain文档说:

如果您的DLL与C运行时库(CRT)链接,则CRT提供的入口点将调用全局和静态C++对象的构造函数和析构函数.因此,DllMain的这些限制也适用于构造函数和析构函数以及从它们调用的任何代码.

由于内的DllMain代码可以使用静态对象,必须DllMain是因为运行DLL_PROCESS_ATTACH之前它运行DLL_PROCESS_DETACH后建造的静态对象,并销毁.

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

可执行程序:

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;
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

这些将打印:

Main, loading library
Moo, constructor
DllMain, DLL_PROCESS_ATTACH
Main, freeing library
DllMain, DLL_PROCESS_DETACH
Moo, destructor
Main, exiting
Run Code Online (Sandbox Code Playgroud)

如您所见,静态对象在之前构造DllMain(...,DLL_PROCESS_ATTACH,...)并在之后销毁DllMain(...,DLL_PROCESS_DETACH,...)