2009-12-14 90 views
4

我在写一个需要多次动态调用一个单独的DLL的DLL。我想保持被调用者加载,然后只卸载我的DLL时卸载它。但据微软称,这是一个bad idea为什么不从调用入口函数调用FreeLibrary?

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

你怎么知道DLL尚未被卸载? – 2009-12-14 19:46:17

+0

@Anon:我不知道。事实上,我不知道它甚至连载入。但如果它已加载并且尚未卸载,我想卸载它。 – 2009-12-14 21:03:00

+0

听起来像你应该静态链接到其他DLL,而不是试图动态加载它。 – 2009-12-15 02:29:32

回答

4

我想我找到了the answer

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

+0

它仍然很模糊,在终止和释放之后会使用库的代码?我假设一个人只释放一个之前加载过的库...并且只有当这个FreeLibrary调用释放对该DLL的最后一个引用时,终止代码才会运行。 – 2014-07-28 01:35:34

2

你不能从你的入口点调用LoadLibrary因为DllMain函数的OS加载程序锁和重新获取该加载程序锁(例如,通过调用LoadLibrary)任何企图内部运行将导致死锁。

+1

但是FreeLibrary呢?会导致什么样的问题? – 2009-12-14 20:56:20

1

不要做任何后果里面的DLLMain。认真。调用FreeLibrary更糟,因为它只会有有时会出现死锁,如果它发生的话,您的免费将refcount递减为零并且库实际上已被释放。

相关问题