Reputation: 117856
I've run into a situation where an application has multiple (incompatible) versions of one or more dll.
app.exe
a.dll // v3.0
...
plugins/foo/foo.dll
plugins/foo/a.dll // v4.0
plugins/foo/...
In this example, app.exe
depends on a.dll
v3.0 and foo.dll
depends on a.dll
v4.0. Due to the search order of LoadLibrary
the a.dll
v3.0 next to my exe is loaded first, then since it's already in memory, the later v4.0 is skipped.
Assuming I cannot:
a.dll
in this case)app.exe
nor foo.dll
to upgrade/downgrade them to a common a.dll
versionIs there a way to load multiple versions of the same-named dll to work around this? I saw this answer regarding AppDomain but that is for managed C# applications, my use case is a native C++ dll.
Upvotes: 8
Views: 1495
Reputation: 595392
What you are looking for is an 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
can use one Activation Context while loading a.dll
v3.0, and use another Activation Context while loading foo.dll
so it uses a.dll
v4.0 instead.
Raymond Chen posted a blog article, How can I specify that my DLL should resolve a DLL dependency from the same directory that the DLL is in?, which covers a scenario very similar to yours:
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
.
Except that his solution uses a manifest-based approach to make the Activation Context of B.DLL
implicitly handled by the system. If you can modify foo.dll
to include a manifest, you can take a similar approach in your situation. Otherwise, you would have to make app.exe
create a new Activation Context manually before loading foo.dll
.
Upvotes: 7