【问题标题】:Does LoadLibrary create distinct instances?LoadLibrary 是否创建不同的实例?
【发布时间】:2011-03-30 16:15:39
【问题描述】:

如果我使用 Win32 API LoadLibrary 连续 3 次加载同一个 DLL,它应该返回 3 个不同的句柄,并且每个库中的函数都应该有不同的地址,对吗? (或者它会做一些“智能”的事情并检测是否已经为进程加载了 dll 并指向同一个模块?)

【问题讨论】:

    标签: winapi loadlibrary


    【解决方案1】:

    它做了一些聪明的事情。 Windows 为通过 LoadLibrary 加载的每个 DLL 保留一个引用计数。这就是为什么您必须为每个相应的 LoadLibrary 调用调用一次 FreeLibrary。假设您没有先释放 DLL,每次调用 LoadLibrary 都会为您提供相同的句柄。

    来自 FreeLibrary 的 MSDN 文档:

    每个进程为每个加载的库模块维护一个引用计数。此引用计数在每次调用 LoadLibrary 时递增,每次调用 FreeLibrary 时递减。

    【讨论】:

    • 请注意,如果您使用不同的路径解析到同一个 DLL,可能会获得多个实例,但大多数人不会遇到这种情况。
    • 好收获。谢谢,迈克尔。
    • 我的一般政策是永远不要调用 FreeLibrary。很高兴知道用户因此可以在同一个上多次调用 LoadLibrary 而不会泄漏过多。 (你真的想在应用程序终止前多久卸载一次库?风险大于价值)。
    【解决方案2】:

    如果它们是同一个 DLL,则不会再次加载它。

    http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx

    "如果指定的模块是一个尚未为调用进程加载的DLL,系统将调用DLL的DllMain函数,其值为DLL_PROCESS_ATTACH。如果DllMain返回TRUE,LoadLibrary返回模块的句柄。如果DllMain返回FALSE ,系统从进程地址空间卸载 DLL,LoadLibrary 返回 NULL。从 DllMain 调用 LoadLibrary 是不安全的。有关详细信息,请参阅 DllMain 中的备注部分。"

    “如果 lpFileName 不包含路径并且有多个加载的模块具有相同的基本名称和扩展名,则该函数返回第一个加载的模块的句柄。”

    【讨论】:

      【解决方案3】:

      不,它没有。为了解决这个问题,您可以将 .dll 复制到一个临时文件中(根据需要多次加载 .dll),然后在完成后删除这些文件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-29
        • 1970-01-01
        • 2021-03-14
        • 2021-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多