使用同一个 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 的多个版本来解决这个问题?我看到了关于 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.

之前手动创建一个新的激活上下文