在同一个进程中加载​​一组DLL的多个副本

背景
我正在维护一个应用程序的插件。 我使用Visual C ++ 2003。

这个插件是由几个DLL组成的 – 这里有主DLL,应用程序使用LoadLibrary加载的DLL,主DLL和其他DLL使用了几个实用程序DLL。
依赖通常看起来像这样:

  • plugin.dll – > utilA.dll,utilB.dll
  • utilA.dll – > utilB.dll
  • utilB.dll – > utilA.dll,utilC.dll

你得到的照片。

DLL之间的一些依赖关系是加载时间和一些运行时间。

所有的DLL文件都存储在可执行文件的目录中(不是必需的,现在它是如何工作的)。

问题
有一个新的要求 – 在应用程序中运行插件的多个实例。
应用程序在其自己的线程中运行插件的每个实例,即每个线程调用由plugin.dll导出的函数。 然而,插件的代码不是线程安全的 – 大量的全局variables等等。

不幸的是,修复整个事情目前还不是一个选项,所以我需要一种方法来在同一个进程中加载​​多个(最多3个)插件DLL的副本。

选项1:独特的名称方法
创build每个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:并排组装方法
创buildDLL文件的3个副本,每个组在其自己的目录中,并通过将程序集清单文件放在目录中,将每个组定义为程序集,列出插件的DLL。
每个DLL将有一个指向程序集的应用程序清单,以便加载程序find驻留在相同目录中的实用程序DLL的副本。 清单需要被embedded,以便在使用LoadLibrary加载DLL时find它。 因为VS2003没有内置清单embedded支持,所以我将使用VS的更高版本中的mt.exe。

我已经尝试了部分成功的方法 – 依赖关系在DLL的加载时发现,而不是当加载另一个DLL的DLL函数被调用时。
这似乎是根据这篇文章预期的行为 – 一个DLL的激活上下文只用于DLL的加载时间,然后它被停用,并使用进程的激活上下文。

编辑:按预期的方式与ISOLATION_AWARE_ENABLED使用 – 运行时加载的DLL使用加载DLL的原始激活上下文。

问题
有其他的select吗? 任何快速和肮脏的解决scheme将做。 🙂

ISOLATION_AWARE_ENABLED甚至可以和VS2003一起工作吗? 编辑:它。

意见将不胜感激。

谢谢!

ISOLATION_AWARE_ENABLED由Windows SDK头文件实现,因此可能根本不值得使用VS2003。 但是,可以下载最新的Windows 7 SDK并将其用于VS2003。

您不需要使用MT链接清单。 清单可以作为资源嵌入到没有明确知识的环境中。

将以下内容添加到dll的.rc文件以嵌入清单。 (最近有足够的平台sdk RT_MANIFEST应该已经定义):

 #define RT_MANIFEST 24 #define APP_MANIFEST 1 #define DLL_MANIFEST 2 DLL_MANIFEST RT_MANIFEST dllName.dll.embed.manifest