【问题标题】:How communicate between two DLLs loaded by same process without loading them again?如何在同一进程加载的两个 DLL 之间进行通信而不再次加载它们?
【发布时间】:2020-05-15 20:18:44
【问题描述】:

我想在一个应用程序中的两个插件之间进行通信。 这两个插件都是 C++ COM DLL。我们称它们为 DLL1 和 DLL2。

在 DLL1 中,我创建了一个加载 COM DLL 的 COM 类的实例。 从 DLL2,我可以创建该 COM 类的类似实例,它可以再次加载该 COM DLL。

基本上,我不想再次从 DLL2 加载该 COM DLL 并以某种方式获取已由 DLL1 加载的该 COM DLL 的句柄。 我可以从 DLL2 调用 COM DLL(由 DLL1 加载)中存在的函数而不再次加载它吗?

这里的限制是,我不想从 DLL2 加载 COM DLL。它将由 DLL1 加载,我只想从 DLL2 执行该 COM DLL 函数。

【问题讨论】:

  • 为什么Windows会在同一个进程中加载​​一个DLL两次?中间会被卸载吗?您是如何确定会发生这种情况的?如果可能的话,你能显示加载“那个 COM DLL”的代码吗?
  • 如果是同一个进程,DLL就不会再加载了

标签: c++ dll com


【解决方案1】:

来自LoadLibrarydocumentation

系统在所有加载的模块上维护每个进程的引用计数。调用 LoadLibrary 会增加引用计数。调用 FreeLibrary 或 FreeLibraryAndExitThread 函数会减少引用计数。当模块的引用计数达到零或进程终止时(无论引用计数如何),系统都会卸载模块。

如果指定的模块是一个尚未为调用进程加载的 DLL,系统将使用 DLL_PROCESS_ATTACH 值调用 DLL 的 DllMain 函数。如果 DllMain 返回 TRUE,则 LoadLibrary 返回模块的句柄。如果 DllMain 返回 FALSE,系统从进程地址空间卸载 DLL,LoadLibrary 返回 NULL。

所以在同一进程中调用LoadLibrary("XXX.dll") 两次只会导致加载库一次,第二次调用应该得到相同的模块句柄。

【讨论】:

  • COM DLL 在从 DLL1 创建 COM 对象的实例时被加载。现在在 DLL2 中,如何知道 COM DLL 在创建 COM 对象之前是否已经加载。
  • 你为什么在乎?再次拨打LoadLibrary是无害的。
  • 我在 DLL1 中创建一个 COM 实例,它调用 COM DLL 的 Dllmain 并加载它。同样,从 DLL2 我正在使用 'comInterfacePtr.CoCreateInstance(__uuidof(COMModule));' 创建一个 COM 实例我没有使用“LoadLibrary”。现在,在 DLL2 中,我只想知道 COM DLL 是否已经加载。
  • 检查GetModuleHandle?我想你没有松耦合的野心,所以不妨检查一下 dll 是否按名称加载
猜你喜欢
  • 2010-10-20
  • 1970-01-01
  • 1970-01-01
  • 2012-06-22
  • 2012-04-30
  • 2017-08-30
  • 1970-01-01
  • 2011-04-13
  • 1970-01-01
相关资源
最近更新 更多