背景
我正在维护一个应用程序的插件。我正在使用 Visual C++ 2003。
该插件由多个 DLL 组成 - 主 DLL,即应用程序使用 LoadLibrary 加载的主 DLL,以及主 DLL 和彼此使用的多个实用程序 DLL。
依赖项通常如下所示:
- plugin.dll -> utilA.dll、utilB.dll
- utilA.dll -> utilB.dll
- utilB.dll -> utilA.dll、utilC.dll
你得到图片。
DLL 之间的一些依赖关系是加载时间和一些运行时间。
所有 DLL 文件都存储在可执行文件的目录中(不是必需的,只是它现在的工作方式)。
问题
有一个新要求——在应用程序中运行插件的多个实例。
应用程序在其自己的线程中运行插件的每个实例,即每个线程调用由plugin.dll 导出的函数。然而,插件的代码不是线程安全的——大量的全局变量等。
不幸的是,修复整个事情目前不是一个选项,所以我需要一种在同一进程中加载插件 DLL 的多个(最多 3 个)副本的方法。
选项 1:不同的名称方法
为每个 DLL 文件创建 3 个副本,以便每个文件都有一个不同的名称。例如plugin1.dll、plugin2.dll、plugin3.dll、utilA1.dll、utilA2.dll、utilA3.dll、utilB1.dll等。应用程序将加载plugin1.dll、plugin2.dll和plugin3.dll。这些文件将位于可执行文件的目录中。
对于每组 DLL 通过名称相互了解(因此相互依赖关系起作用),需要在编译时知道名称 - 这意味着 DLL 需要编译多次,只有每次使用不同的输出文件名。
不是很复杂,但我讨厌拥有 3 个 VS 项目文件的副本,并且不喜欢一遍又一遍地编译相同的文件。
选项 2:并行程序集方法
创建 DLL 文件的 3 个副本,每个组在其自己的目录中,并通过将程序集清单文件放入目录中来将每个组定义为程序集,列出插件的 DLL。
每个 DLL 都有一个指向程序集的应用程序清单,以便加载程序找到位于同一目录中的实用程序 DLL 的副本。需要嵌入清单,以便在使用 LoadLibrary 加载 DLL 时找到它。我将使用更高版本的 VS 中的 mt.exe 来完成这项工作,因为 VS2003 没有内置的清单嵌入支持。
我已经尝试了这种方法并取得了部分成功——在 DLL 的加载期间发现了依赖关系,但在调用加载另一个 DLL 的 DLL 函数时却没有。根据这篇文章
,这似乎是预期的行为- DLL 的激活上下文仅在 DLL 的加载时使用,之后它被停用并使用进程的激活上下文。
编辑:按预期工作ISOLATION_AWARE_ENABLED
- DLL 的运行时加载使用加载 DLL 的原始激活上下文。
有
任何其他选择吗?任何快速而肮脏的解决方案都可以。:-)
ISOLATION_AWARE_ENABLED
甚至可以与 VS2003 一起使用吗?编辑:确实如此。
评论将不胜感激。
谢谢!