【发布时间】:2011-03-30 16:15:39
【问题描述】:
如果我使用 Win32 API LoadLibrary 连续 3 次加载同一个 DLL,它应该返回 3 个不同的句柄,并且每个库中的函数都应该有不同的地址,对吗? (或者它会做一些“智能”的事情并检测是否已经为进程加载了 dll 并指向同一个模块?)
【问题讨论】:
标签: winapi loadlibrary
如果我使用 Win32 API LoadLibrary 连续 3 次加载同一个 DLL,它应该返回 3 个不同的句柄,并且每个库中的函数都应该有不同的地址,对吗? (或者它会做一些“智能”的事情并检测是否已经为进程加载了 dll 并指向同一个模块?)
【问题讨论】:
标签: winapi loadlibrary
它做了一些聪明的事情。 Windows 为通过 LoadLibrary 加载的每个 DLL 保留一个引用计数。这就是为什么您必须为每个相应的 LoadLibrary 调用调用一次 FreeLibrary。假设您没有先释放 DLL,每次调用 LoadLibrary 都会为您提供相同的句柄。
来自 FreeLibrary 的 MSDN 文档:
每个进程为每个加载的库模块维护一个引用计数。此引用计数在每次调用 LoadLibrary 时递增,每次调用 FreeLibrary 时递减。
【讨论】:
如果它们是同一个 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 不包含路径并且有多个加载的模块具有相同的基本名称和扩展名,则该函数返回第一个加载的模块的句柄。”
【讨论】:
不,它没有。为了解决这个问题,您可以将 .dll 复制到一个临时文件中(根据需要多次加载 .dll),然后在完成后删除这些文件。
【讨论】: