2

背景
我正在维护一个应用程序的插件。我正在使用 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 一起使用吗?编辑:确实如此。

评论将不胜感激。

谢谢!

4

1 回答 1

0

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
于 2010-05-02T14:09:29.913 回答