【问题标题】:Same DLL loaded twice in a process同一个 DLL 在一个进程中加载​​了两次
【发布时间】:2010-10-20 15:38:43
【问题描述】:

我有一个 ActiveX 控件 (foo.dll),当我在 IE 中嵌入它并启动页面时。我可以看到进程资源管理器显示了从同一位置加载的 foo.dll 的两个实例。

这会导致 DLL_PROCESS_ATTACH 被调用两次,并且全局数据结构被初始化两次。

有没有办法解决这个问题? windows loader 是如何工作的?

谢谢, 维卢

【问题讨论】:

  • 这是一个混合模式的应用程序吗?如果是这样,那么如果您还有多个 AppDomain,那么可以加载相同的 DLL,但在每个 AppDomain 中。
  • 我以前见过这种情况,一次被映射为“图像”,另一个被映射为不同基址和大小的“数据”

标签: winapi com activex


【解决方案1】:

DLL_PROCESS_ATTACH 每个 DLL 实例只能调用一次。 . . DLL 是否在相同的基地址加载,即 DllMain 中的 HINSTANCE 是否相同?它们是从完全相同的路径加载的吗?不同的路径导致不同的加载模块。是否在两个负载之间卸载?你确定你看到的是DLL_PROCESS_ATTACH 而不是DLL_THREAD_ATTACH

【讨论】:

  • 嗨 Micheal,令人惊讶的是,这两个实例都是从同一路径加载的,而 DLL_PROCESS_ATTACH 就是我所指的 ..
  • DLL 是否在两者之间被卸载?您可以将代码发布到您的 DllMain 吗?
【解决方案2】:

LoadLibraryEx 包含如何处理 dll 的额外标志。我怀疑这就是你看到它不止一次出现的原因。

【讨论】:

    【解决方案3】:

    一种解决方法是使用单例初始化函数来保护您的全局数据。

    你到底有多少个全局结构?

    【讨论】:

      【解决方案4】:

      每当进程加载 DLL 时,都会调用 DLL_PROCESS_ATTACH。

      使用计数器确定附加了多少进程,并且仅在第一个附加时进行初始化。

      您还需要在 DLL 实例之间设置 share memory,并将计数器以及您只想初始化一次的全局内存存储在其中。

      【讨论】:

        【解决方案5】:

        我不确定,但我认为观察可以解释为您引用的 dll 正在实例化定义为 STA(单线程单元)的 COM (ActiveX) 对象。任何引用 STA com 对象的 .Net dll 都会在内存中为使用这些 COM 对象的每个线程加载一个新图像。 至少这是我们看起来会发生的行为。

        【讨论】:

          猜你喜欢
          • 2017-08-30
          • 2011-06-28
          • 2010-12-07
          • 1970-01-01
          • 1970-01-01
          • 2020-05-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多