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

发布于 2024-08-14 22:53:00 字数 765 浏览 4 评论 0原文

我正在编写一个 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;
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

水波映月 2024-08-21 22:53:00

我想我已经找到了答案

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

I think I've found the answer.

The entry-point function should
perform only simple initialization or
termination tasks. It must not call
the LoadLibrary or LoadLibraryEx
function (or a function that calls
these functions), because this may
create dependency loops in the DLL
load order. This can result in a DLL
being used before the system has
executed its initialization code.
Similarly, the entry-point function
must not call the FreeLibrary function
(or a function that calls FreeLibrary)
during process termination, because
this can result in a DLL being used
after the system has executed its
termination code.

五里雾 2024-08-21 22:53:00

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

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.

街道布景 2024-08-21 22:53:00

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文