Destructor of C++ in a DLL

sable93

资深人士
VIP
注册
2003-11-11
消息
1,222
荣誉分数
92
声望点数
208
我有一个class,要求有人用的时候就initialize and work,但不知道什么时候没人用了,所以我就作为一个global variable放在DLL里,等destructor时我再cleanup。但我发现在某种场合destructor再cleanup时已经太晚了,那时候DLL都unload了。有没有什么好办法让它自动提前cleanup,又做到it is the last one.
请DX们指教,谢谢各位。
 
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
UNREFERENCED_PARAMETER(lpReserved);

if (dwReason == DLL_PROCESS_ATTACH)
{
if (!AfxInitExtensionModule(L2ExtendDLL, hInstance))
return 0;
new CDynLinkLibrary(L2ExtendDLL);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
AfxTermExtensionModule(L2ExtendDLL);<------
}
return 1;
}
 
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:<------
case DLL_PROCESS_DETACH:<------
break;
}
return TRUE;
}
 
Thanks for your quick reply, unfortunately it is too late too.
There are 2 threads in the DLL, at cleaning up, main thread sends an event to ask sub-thread to exit, and main thread is waiting for it died. But the sub-thread will be deadklock in _endthreadex or more directly in System Call ExitThread.
I do not want to somebody else to cleanup for it, I would like to do it by itself.
MS mentioned that "Warning There are serious limits on what you can do in a DLL entry point." I do not know it is only in Initialization or also includes the "Cleanup" stage, if it does, then the way I did is not correct.
Thanks a lot,
 
Thanks a lot, found a work around for it but I really need to know how to solve this kind of problem.
God bless me, and you too!
 
The workaround would be expose a function which does the cleanup, and create a wrapper DLL which calls the clean function upon being unloaded, and the client should use the wrapper DLL instead.

Unlike other resources, threads cannot be stopped from dllmain or after DLL has been unloaded, they must be stopped explicitly before dll was going to be unloaded.

If your DLL is a COM server, you can put cleanup code in the destructor of COM object because the module reference count can hold the DLL in memory.
 
请教:
假定ReleaseIt()是send event to sub-thread and wait for it died, 那Wrapper DLL什么时候call它呢?
谢谢
 
Sorry, that's my mistake. Wrapper DLL doesn't help freeing thread resources. I was assuming calling releaseit from the dllmain of wrapper thread, but that would only cause trouble because the detach of the thread would call back and hit dllmain of wrapper DLL and then it's a deadlock because system synchronizes the dllmain.

It looks like you can only rely on the client process to help you to free the thread resources, unless you can modify your code to provide functionality through COM objects.

I had exactly same problem as you (cleaning threads when dll is being unloaded and do not want help from client process). I was luck because we are using COM.
 
It is a component used very frequently. It was COM, for performance reason, we are going to change to pure C++ DLL.
Thanks a lot.
 
后退
顶部