4

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

入口点函数只应执行简单的初始化任务,不应调用任何其他 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;
}
4

3 回答 3

4

我想我找到了答案

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

于 2009-12-14T21:24:54.923 回答
2

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

于 2009-12-14T19:57:17.360 回答
2

不要在 DLLMain 内做任何有影响的事情。严重地。调用 FreeLibrary 更糟糕,因为它有时只会死锁,如果碰巧你的 free 将 refcount 减少到零并且库实际上被释放了。

于 2009-12-14T21:27:05.497 回答