LoadLibrary是否创建不同的实例?

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

27

它实现了一些智能功能。Windows通过LoadLibrary为每个已加载的DLL保留引用计数。这就是为什么每次对应的LoadLibrary调用后,您都必须调用FreeLibrary一次的原因。假设您没有先释放DLL,那么每次调用LoadLibrary将会给您相同的句柄。

根据MSDN文档中关于FreeLibrary的说明:

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


10
请注意,如果您使用不同的路径解析到相同的 DLL,可能会得到多个实例,但大多数人不会遇到这种情况。 - Michael
3
我的一般策略是永远不要调用FreeLibrary。知道用户可以在同一个库上多次调用LoadLibrary而不会泄漏更多的资源是很好的。(你真的想在应用程序终止之前卸载库的频率有多高?风险大于价值)。 - CashCow

8
如果它们是同一个DLL,则不会再次加载它。 http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx “如果指定的模块是尚未为调用进程加载的DLL,则系统使用DLL_PROCESS_ATTACH值调用DLL的DllMain函数。如果DllMain返回TRUE,则LoadLibrary返回模块的句柄。如果DllMain返回FALSE,则系统会从进程地址空间卸载DLL,并且LoadLibrary返回NULL。不能从DllMain中调用LoadLibrary。有关详细信息,请参阅DllMain中的备注部分。”
“如果lpFileName不包括路径并且有多个已加载的模块具有相同的基本名称和扩展名,则该函数返回加载第一个模块的句柄。”

4
不,它不会。为了避免这种情况,你可以将 .dll 文件复制到一个临时文件中(加载 .dll 的次数取决于需要的次数),然后在完成后删除这些文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接