【问题标题】:Load a DLL More Than Once?多次加载 DLL?
【发布时间】:2012-02-08 09:43:49
【问题描述】:

我正在使用LoadLibrary 函数在Windows 中加载一个DLL。我的问题是:如果我为同一个 DLL 多次调用此方法,我是否会获得 DLL 的不同实例的句柄,还是它们都引用同一个实例?

此外,这种行为与 Linux SO 文件有何关联,是相同还是完全不同,在这方面我可以做出哪些假设?谢谢。

【问题讨论】:

  • 您想要一个单独的 DLL 实例(及其全局状态)吗?
  • @DavidHeffernan 可能,但前提是它也可以在 Linux 中完成。我更想弄清楚事情“通常”是如何运作的。如果您所描述的可能,我很想知道如何。
  • 它在操作系统中的工作方式相同。获取 DLL 的单独实例有一个肮脏的技巧。每次需要新实例时,将文件复制到临时位置并为其指定一个唯一名称。这样你就可以强制系统加载一个新模块。由于糟糕的设计和全局状态的使用,我有时会使用这种技术来解决不是线程安全的库。
  • @DavidHeffernan - 请记住,文件的路径不是决定因素,它是标识它的文件名。跨度>
  • @polynomial 不是这样。加载两个同名但在不同文件夹中的 DLL 将导致加载两个不同的模块。你说的我认为是 16 位 Windows 的情况。

标签: c++ windows linux dll shared-libraries


【解决方案1】:

MSDN 文档指出:

系统对所有加载的进程维护一个每个进程的引用计数 模块。调用 LoadLibrary 会增加引用计数。打电话 FreeLibrary 或 FreeLibraryAndExitThread 函数递减 参考计数。系统在其引用计数时卸载模块 达到零或进程终止时(无论 引用计数)。

因此,似乎多次加载模块(不匹配对 FreeLibrary 的调用)将返回相同的句柄。

【讨论】:

    【解决方案2】:

    如果 DLL 已经加载,LoadLibrary 将简单地返回内存中库的地址。但是,在尝试第二次加载时,不会再次使用 DLL_PROCESS_ATTACH 调用 DllMain。库意义上的句柄只是内存位置,因此第二次获得的值应该与第一次相同。

    就 linux SO 文件而言,我也不明白为什么它们会加载两次。但是,其他人必须对此进行权衡才能给您正确的答案。

    【讨论】:

      【解决方案3】:

      对于 Linux 共享对象,来自dlopen(3) manpage

      如果用dlopen()再次加载同一个库,同一个文件 返回句柄dl 库维护引用计数 库句柄,所以动态库直到 dlclose() 被调用的次数与dlopen() 一样多 成功了_init() 例程(如果存在)仅调用一次。 但是随后使用RTLD_NOW 调用可能会强制解析符号 之前加载了RTLD_LAZY 的库。

      【讨论】:

      • 这是针对每个进程还是针对所有进程?
      • @g19fanatic - 同一个进程。
      • 对于 Linux,您可以使用 dlmopen()
      猜你喜欢
      • 1970-01-01
      • 2012-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-10
      • 2018-08-22
      相关资源
      最近更新 更多