为什么不从入口点函数调用FreeLibrary?

时间:2009-12-14 19:40:50

标签: c++ windows dll winapi entry-point

我正在编写一个需要动态多次调用单独DLL的DLL。我想保持被调用者加载,然后卸载我的DLL时卸载它。但根据微软的说法,这是一个bad idea

  

入口点功能应该只   执行简单的初始化任务   并且不应该调用任何其他DLL   加载或终止功能。对于   例如,在入口点函数中,   你不应该直接或间接地   调用LoadLibrary函数或   LoadLibraryEx函数。另外,   你不应该打电话给FreeLibrary   过程时的功能   终止。

这是有问题的代码。有人可以解释为什么我不应该从DLL的入口点调用LoadLibrary和FreeLibrary吗?

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;
}

3 个答案:

答案 0 :(得分:4)

我想我找到了the answer

  

入口点功能应该   只执行简单的初始化或   终止任务。一定不要打电话   LoadLibrary或LoadLibraryEx   函数(或调用的函数)   这些功能),因为这可能   在DLL中创建依赖循环   加载订单。这可能会导致DLL   在系统使用之前使用   执行其初始化代码。   同样,入口点功能   不得调用FreeLibrary函数   (或调用FreeLibrary的函数)   在流程终止期间,因为   这可能导致使用DLL   系统执行完之后   终止码。

答案 1 :(得分:2)

您无法从入口点调用LoadLibrary,因为DllMain函数在OS加载程序锁内运行,任何重新获取加载程序锁的尝试(例如,通过调用LoadLibrary)都将导致死锁。

答案 2 :(得分:2)

不要在DLLMain中执行任何后果。认真。调用FreeLibrary甚至更糟,因为它只会有时死锁,如果它发生了你的自由将refcount减少到零并且库实际上已被释放。