我正在编写一个定义全局静态对象的DLL。
在对象的构造函数中,我正在做一些可能成功或可能不成功的初始化。
是否可以在DllMain()中指示初始化过程的成功或失败?首先叫哪两个?
谢谢。
答案 0 :(得分:26)
MSDN的DllMain文档说:
如果您的DLL与C链接 运行时库(CRT),条目 由CRT提供的点呼叫 构造函数和析构函数 全局和静态C ++对象。 因此,这些限制 DllMain也适用于构造函数和 析构函数和任何代码 从他们那里打来电话。
由于DllMain中的代码可能使用静态对象,因此必须在为DLL_PROCESS_ATTACH运行DllMain之前构造静态对象,并在为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,...)
之后销毁