Determine the loaded path for DLLs

c++, dll, visual-studio, windows

Solution

You want to load two different DLLs with the same name (common.dll) into the same process.

That seems like a bad idea to me. Is it really necessary? Could one of them be renamed?

Ensuring the DLLs you load can find other DLLs which aren't in the search path.

(If you were not dynamically loading DLL.dll and DLL2.dll then I'm not sure what the would be. Luckily, I see you are. :))

If you are dynamically loading DLL.dll and DLL2.dll (that is, using LoadLibrary at runtime instead of linking to their .lib files at build time), then you can call SetDllDirectory beforehand to explicitly add the DLL or DLL2 directories to the search path. You would want to only have one directory in the path at once to ensure the right common.dll was loaded.

Note that it is good practice, unless it breaks a poorly-written component, to call SetDllDirectory("") at the start of your program to remove the current-working-directory (not the program's directory, don't worry) from the DLL search path. This mitigates security issues where your code can be tricked into loading DLLs. But also note that if you reset the search path by calling SetDllDirectory(NULL) then you need to call SetDllDirectory("") again afterwards.

So you'd have code like this:

SetDllDirectory(NULL); // Reset.
SetDllDirectory(""); // Plug "binary planting" security hole. `
SetDllDirectory("C:\MyExePath\DLL");
LoadLibrary("C:\MyExePath\DLL\DLL.dll");

SetDllDirectory(NULL); // Reset.
SetDllDirectory(""); // Plug "binary planting" security hole.
SetDllDirectory("C:\MyExePath\DLL2");
LoadLibrary("C:\MyExePath\DLL2\DLL2.dll");

SetDllDirectory(NULL); // Reset.
SetDllDirectory(""); // Plug "binary planting" security hole.

(Untested so apologies for any mistakes or missing arguments. Should give you the idea, though.)

(You should calculate the C:\MyExePath at runtime. Hard-coding it would be bad, obviously.)

(I am assuming that DLL.dll and DLL2.dll load their common.dll implicitly. If they are loading common.dll via a LoadLibrary call then the problem is even easier: Just make them calculate their own paths and then pass LoadLibrary the full path to common.dll.)

Beware: SetDllDirectory affects your entire process. If your process has multiple threads you should ensure the SetDllDirectory calls are isolated from each other as well as anything else that may trigger a LoadLibrary call. e.g. Load the libraries at startup before you spawn any other thread, if possible.

Problem

I wish to have my application in the following structure. ``` Exe | |----- DLL\DLL.dll, DLL\common.dll | |----- DLL2\DLL2.dll, DLL2\common.dll ``` My EXE will load the DLLs through ``` LoadLibraryEx(_T("DLL\\DLL.dll"), 0, 0); LoadLibraryEx(_T("DLL2\\DLL2.dll"), 0, 0); ``` `DLL.dll` and `DLL2.dll` project will link against `common.dll` through lib file. There will be 2 different versions of `common.dll` though. However, during execution, `Exe` expected me to place `common.dll` same directory as `Exe`, but not same directory as `DLL` and `DLL2`. Is there any way I can resolve this, by able to have the above directory structure. Yet, still use lib to link against `DLL/DLL2` with `common`.

Original source

Related problems