views:

677

answers:

5

I'm using two commercial libraries that are produced by the same vendor, called VendorLibA and VendorLibB. The libraries are distributed as many DLLs that depend on the compiler version (e.g. VC7, VC8). Both libraries depend on a another library, produced by this vendor, called VendorLibUtils and contained in one DLL.

The problem: VendorLibA uses a different version of VendorLibUtils than VendorLibB. The two versions are not binary compatible, and even if they were it would be a bad idea to use the wrong version.

Is there any way I could use the two libraries under the same process?

Note: LoadLibrary can't solve this since my process is not that one that's importing VendorLibUtils.

EDIT: Forgot to mention the obvious, I don't have to source code for any of the commercial libraries and probably I will never have (sigh).

EDIT: The alternative btw, is to do this: http://stackoverflow.com/questions/312569/how-to-combine-gui-applications-in-windows

+1  A: 

I'm no expert in DLLs, but the only way I see it possible would be to use LoadLibrary() and explicitly load the DLLs. Then you could place the functions/classes etc in separate namespaces using GetProcAddress().

HMODULE v1 = LoadLibrary(_T("libv1_0.dll"));
libv1_0::fun_in_lib = reinterpret_cast<FUNTYPE>(GetProcAddress(v1, _T("fun_in_lib"));

and

HMODULE v2 = LoadLibrary(_T("libv2_0.dll"));
libv2_0::fun_in_lib = reinterpret_cast<FUNTYPE>(GetProcAddress(v2, _T("fun_in_lib"));

Whether this would work or not still kind of depends on the library, so it may or may not work, but as far as I can tell it's the only possibility.

Andreas Magnusson
+1  A: 

As you are not using VendorLibUtils directly, I assume you can't use LoadLibrary etc.

If the VendorLibUtils DLLs only have exports by ordinal, you could probably rename one of the the libraries and patch the corresponding VendorLib*X* to use a different filename for its imports.

If the VendorLibUtils DLLs have one or more exported symbols with the same names, you might need to patch the imports and export tables too, but let's hope not! :-)

divideandconquer.se
Exported by name it is :/. Any Google search words for this?
kshahar
Make a test application and four DLLs that reproduces this scenario, to see if you can have the same symbol name in the two "TestLibUtils" DLLs and that the TestLibA and TestLibB runs the right function.
divideandconquer.se
+2  A: 

I think your most promising option is to complain, loudly, to the vendor who is distributing mutually incompatible products. That rather goes against the idea of a DLL.

You can't just put the DLLs in different directories. Once a DLL with a given name is loaded, all other attempts to load another DLL with the same module name will simply use the one that's already loaded, even if the paths are different.

From that, we can conclude that to load two copies of VendorLibUtils, one copy needs to have a different name. You can't just rename the DLL file; the code in your program won't know to look for the different file. Therefore, perhaps there's a way to edit the import table of VendorLibB to make it think the functions it needs are in VendorLibUtilsB.dll instead of just VendorLibUtils.dll. I'm afraid I don't know of any utility that will do that, but I have little doubt it's possible to do.

Rob Kennedy
+1  A: 

As someone else mentioned, you could rename one of the copies of VendorLibUtils and modify the import table of the associated VendorLib DLL to link to it, rather than the VendorLibUtils.dll it was created with.

There's a few tools out there that let you edit EXE/DLL files in this way. CFF Explorer is a pretty decent one which allows editing of the import table. If you open up the VendorLib DLL in it and go to the Import Directory section (in the tree on the left), you'll see a list of modules at the top of the main window. You can rename the module by double-clicking on its name. Then you just save the DLL and it should now use your renamed VendorLibUtils DLL.

Of course, this assumes that VendorLib uses the import table to access VendorLibUtils, which it may not -- it may use LoadLibrary/GetProcAddress, in which case you won't see an import table entry for VendorLibUtils.

Actually, if the VendorLib does use the import table but also uses LoadLibrary to access the VendorLibUtils DLL in some places (I've seen it done), those places will still use the wrong one. If you rename both libraries, you might at least see an error if this is the case (since a DLL with the original name won't exist now). There is a way to deal with this if it occurs, but it starts to get quite complicated at this point, so I won't elaborate unless you really want/need to know.

DarthPingu
+1  A: 

You mean, you have a situation similar to MSVCRT80.DLL and MSVCRT90.DLL ? There is a good reason Microsoft numbered these DLLs.If both were called MSVCRT.DLL, only one of them would be loaded in a single process.

MSalters
The situation I have is the one where both DLLs are called MSVCRT.DLL, but are different in their content.
kshahar