I'm writing a DLL that needs to call a separate DLL dynamically multiple times. I would like to keep the callee loaded and then just unload it when my DLL is unloaded. But according to Microsoft, that's a bad idea.
The entry point function should only perform simple initialization tasks and should not call any other DLL loading or termination functions. For example, in the entry point function, you should not directly or indirectly call the LoadLibrary function or the LoadLibraryEx function. Additionally, you should not call the FreeLibrary function when the process is terminating.
Here's the offending code. Can somebody explain why I shouldn't call LoadLibrary and FreeLibrary from my DLL's entry point?
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call) {
case DLL_PROCESS_DETACH :
if (hLogLib != NULL) FreeLibrary(hLogLib);
break;
}
return TRUE;
}
I think I've found the answer.
You can't call LoadLibrary from your entry point because the DllMain function runs inside an OS loader lock and any attempts to reacquire that loader lock (for instance, by calling LoadLibrary) will result in deadlock.
Don't do anything of consequence inside of DLLMain. Seriously. Calling FreeLibrary is even worse because it'll only sometimes deadlock, if it happens that your free decrements the refcount to zero and the library is actually freed.