背景
我正在为应用程序维护一个插件。我正在使用Visual C ++ 2003.
该插件由几个DLL组成 - 主要的DLL是应用程序使用LoadLibrary加载的DLL,并且主DLL和彼此使用了几个实用程序DLL。 依赖关系通常如下所示:
你明白了。
DLL之间的一些依赖关系是加载时和一些运行时。
所有DLL文件都存储在可执行文件的目录中(不是要求,现在它是如何工作的。)
问题
有一个新的要求 - 在应用程序中运行插件的多个实例
应用程序在其自己的线程中运行插件的每个实例,即每个线程调用plugin.dll导出的函数。但是,插件的代码不是线程安全的 - 许多全局变量等等。
不幸的是,修复整个事情目前不是一个选项,所以我需要一种方法在同一个进程中加载多个(最多3个)插件DLL的副本。
选项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:并排式装配方法
创建3个DLL文件副本,每个组在其自己的目录中,并通过将程序集清单文件放在目录中来定义每个组作为程序集,列出插件的DLL。
每个DLL都有一个指向程序集的应用程序清单,以便加载程序找到驻留在同一目录中的实用程序DLL的副本。当使用LoadLibrary加载DLL时,需要嵌入清单以便找到它。我将从后来的VS版本中使用mt.exe来完成这项工作,因为VS2003没有内置的清单嵌入支持。
我尝试了这种方法并取得了部分成功 - 在DLL的加载时间内发现了依赖关系,但是当调用加载另一个DLL的DLL函数时却没有。 这似乎是根据this article的预期行为 - DLL的激活上下文仅在DLL的加载时使用,之后它被停用并且使用进程的激活上下文。
编辑:按预期使用ISOLATION_AWARE_ENABLED
- DLL的运行时加载使用加载DLL的原始激活上下文。
问题
还有其他选择吗?任何快速&脏的解决方案会做。 : - )
ISOLATION_AWARE_ENABLED
甚至可以使用VS2003吗? 修改:确实如此。
将非常感谢评论。
谢谢!
答案 0 :(得分:0)
ISOLATION_AWARE_ENABLED
由Windows SDK头文件实现,因此可能根本不值得使用VS2003。但是,可以下载最新的Windows 7 SDK并将其与VS2003一起使用。
您无需使用MT链接清单。清单可以作为资源嵌入到没有明确知识的环境中。
将以下内容添加到dll的.rc文件中以嵌入清单。 (最近有足够的平台,应该已经定义了RT_MANIFEST):
#define RT_MANIFEST 24
#define APP_MANIFEST 1
#define DLL_MANIFEST 2
DLL_MANIFEST RT_MANIFEST dllName.dll.embed.manifest