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

Windows 在同一进程中加载一组DLL的多个副本,windows,dll,manifest,loadlibrary,Windows,Dll,Manifest,Loadlibrary,背景 我正在维护一个应用程序的插件。我使用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文件都存储在可执行文件的目录

背景 我正在维护一个应用程序的插件。我使用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导出的函数。然而,插件的代码绝不是线程安全的——有很多全局变量等等

不幸的是,修复整个问题目前还不是一个选项,所以我需要一种方法在同一个过程中加载插件DLL的多个副本,最多3个副本

选项1:不同名称方法 创建每个DLL文件的3个副本,以便每个文件都有一个不同的名称。e、 g.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的加载时使用,然后它被停用,进程的激活上下文被使用

编辑:按预期启用隔离\u感知\u-DLL的运行时加载使用加载DLL的原始激活上下文

问题 还有其他选择吗?任何快速且肮脏的解决方案都可以:-

隔离\u-AWARE\u-ENABLED甚至可以与VS2003一起使用吗?编辑:是的

如有评论,将不胜感激

谢谢

隔离感知功能由Windows SDK头文件实现,因此可能根本不值得使用VS2003。但是,可以下载最新的Windows7SDK并将其与VS2003一起使用

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

将以下内容添加到dll的.rc文件以嵌入清单。对于最近足够多的平台sdk,应已定义RT_清单:

#define RT_MANIFEST 24 
#define APP_MANIFEST 1
#define DLL_MANIFEST 2

DLL_MANIFEST RT_MANIFEST dllName.dll.embed.manifest
支持隔离的由Windows SDK头文件实现,因此VS2003可能根本不值得。但是,可以下载最新的Windows7SDK并将其与VS2003一起使用

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

将以下内容添加到dll的.rc文件以嵌入清单。对于最近足够多的平台sdk,应已定义RT_清单:

#define RT_MANIFEST 24 
#define APP_MANIFEST 1
#define DLL_MANIFEST 2

DLL_MANIFEST RT_MANIFEST dllName.dll.embed.manifest

隔离意识启用实际上与VS2003一起工作,我想它附带的SDK足够新,可以包括winsxs支持。我没有意识到使用.rc文件嵌入清单-感谢info.ISOLATION\u-aware\u的启用实际上可以与VS2003一起工作,我想它附带的SDK足够新,可以包含winsxs支持。我不知道使用.rc文件嵌入清单-谢谢你提供的信息。