使用同一个 DLL 的多个版本
Using multiple versions of same DLL
我 运行 遇到这样一种情况,即应用程序具有一个或多个 dll 的多个(不兼容)版本。
app.exe
a.dll // v3.0
...
plugins/foo/foo.dll
plugins/foo/a.dll // v4.0
plugins/foo/...
在此示例中,app.exe
依赖于 a.dll
v3.0,foo.dll
依赖于 a.dll
v4.0。由于 search order of LoadLibrary
首先加载我的 exe 旁边的 a.dll
v3.0,然后因为它已经在内存中,所以跳过了后面的 v4.0。
假设我不能:
- 重命名依赖的 dll(在本例中为
a.dll
)
- 将
app.exe
和 foo.dll
修改为 upgrade/downgrade 到通用 a.dll
版本
有没有办法加载同名 dll 的多个版本来解决这个问题?我看到了关于 AppDomain 的 this answer,但那是针对托管 C# 应用程序的,我的用例是本机 C++ dll。
您要找的是 Activation Context:
Activation contexts are data structures in memory containing information that the system can use to redirect an application to load a particular DLL version, COM object instance, or custom window version. One section of the activation context may contain DLL redirection information which is used by the DLL loader; another section may contain COM server information. The activation context functions use, create, activate, and deactivate activation contexts. The activation functions can redirect the binding of an application to version-named objects that specify particular DLL versions, window classes, COM servers, type libraries, and interfaces. For more information about the activation context functions and structures, see the Activation Context Reference.
app.exe
可以在加载 a.dll
v3.0 时使用一个激活上下文,而在加载 foo.dll
时使用另一个激活上下文,因此它使用 a.dll
v4.0 .
Raymond Chen 发布了一篇博客文章,How can I specify that my DLL should resolve a DLL dependency from the same directory that the DLL is in?,其中涵盖了与您非常相似的场景:
A customer had a program that loaded two DLLs, let’s call them A.DLL
and B.DLL
. Both of those DLLs use a common helper DLL called C.DLL
. The catch is that the two DLLs want to use different incompatible versions of C.DLL
. The two DLLs A.DLL
and B.DLL
reside in separate folders, and each folder has a corresponding copy of C.DLL
.
除了他的解决方案使用基于清单的方法使 B.DLL
的激活上下文由系统隐式处理。如果您可以修改 foo.dll
以包含清单,则可以在您的情况下采用类似的方法。否则,您必须 app.exe
在加载 foo.dll
.
之前手动创建一个新的激活上下文
我 运行 遇到这样一种情况,即应用程序具有一个或多个 dll 的多个(不兼容)版本。
app.exe
a.dll // v3.0
...
plugins/foo/foo.dll
plugins/foo/a.dll // v4.0
plugins/foo/...
在此示例中,app.exe
依赖于 a.dll
v3.0,foo.dll
依赖于 a.dll
v4.0。由于 search order of LoadLibrary
首先加载我的 exe 旁边的 a.dll
v3.0,然后因为它已经在内存中,所以跳过了后面的 v4.0。
假设我不能:
- 重命名依赖的 dll(在本例中为
a.dll
) - 将
app.exe
和foo.dll
修改为 upgrade/downgrade 到通用a.dll
版本
有没有办法加载同名 dll 的多个版本来解决这个问题?我看到了关于 AppDomain 的 this answer,但那是针对托管 C# 应用程序的,我的用例是本机 C++ dll。
您要找的是 Activation Context:
Activation contexts are data structures in memory containing information that the system can use to redirect an application to load a particular DLL version, COM object instance, or custom window version. One section of the activation context may contain DLL redirection information which is used by the DLL loader; another section may contain COM server information. The activation context functions use, create, activate, and deactivate activation contexts. The activation functions can redirect the binding of an application to version-named objects that specify particular DLL versions, window classes, COM servers, type libraries, and interfaces. For more information about the activation context functions and structures, see the Activation Context Reference.
app.exe
可以在加载 a.dll
v3.0 时使用一个激活上下文,而在加载 foo.dll
时使用另一个激活上下文,因此它使用 a.dll
v4.0 .
Raymond Chen 发布了一篇博客文章,How can I specify that my DLL should resolve a DLL dependency from the same directory that the DLL is in?,其中涵盖了与您非常相似的场景:
A customer had a program that loaded two DLLs, let’s call them
A.DLL
andB.DLL
. Both of those DLLs use a common helper DLL calledC.DLL
. The catch is that the two DLLs want to use different incompatible versions ofC.DLL
. The two DLLsA.DLL
andB.DLL
reside in separate folders, and each folder has a corresponding copy ofC.DLL
.
除了他的解决方案使用基于清单的方法使 B.DLL
的激活上下文由系统隐式处理。如果您可以修改 foo.dll
以包含清单,则可以在您的情况下采用类似的方法。否则,您必须 app.exe
在加载 foo.dll
.