views:

32

answers:

2

In Visual Studio, you create a .dll project and it creates a .dll and .lib files. You link statically to the .lib, and if the .dll is in the same folder as the .exe, everything works.

I suspect that everything would also work if the .dll was in System32 or any other PATH folder (confirm or correct, please).

But here's the question: I want my exe to find the .dll in ./DLLS/ folder, that is, if my exe is in ....../MyApp/MyApp.exe then it should look for the .dll in ...../MyApp/DLLS/MyDll.dll. I DO NOT want to include the DLLS folder in path. Is there any way I can do this?

Please note that I do not wish to use LoadLibrary explicitly, so I can't specify the path there.

Thanks in advance for any help.

+2  A: 

You could use SetDllDirectory for this. The loader will use the additional directory you specify when loading libraries. There can only be one additional directory, however, so you need to make sure that there aren't other calls to this at a later point in your application, otherwise the directory you specify will be ignored.

If that API does not allow relative directories (I'm not sure), you could always call GetModuleFileName with a NULL first parameter to get the file name of the currently executing program. With a little string manipulation, you can get the absolute path to your DLLs folder.

Chris Schmich
@Chris: And where exactly should I use it? Before the attempt to load the dll, right? but in the scenario described (link statically to lib which loads the dll automatically) the dll is loaded at startup...
Armen Tsirunyan
@Armen: good point, yes, it should be done before the DLL is loaded. If you don't use the DLL immediately in your application, you can specify it to be a delay-load dependency (see http://msdn.microsoft.com/en-us/library/yx9zd12s.aspx). This will prevent the DLL from loading until you make your first call into it. This is similar to calling `LoadLibrary`, but it is done for you automatically.
Chris Schmich
+2  A: 

Here is the default sequence which Win32 applications go through when looking for a DLL:

http://msdn.microsoft.com/en-us/library/7d83bc18(VS.80).aspx

So according to this, another approach might be to call SetCurrentDirectory or SetDllDirectory. But in order for this to work you have to use the Delay Loaded Library functionality (you specify that in Project Settings in Visual Studio). Delay loaded library means that the DLL is loaded only at the moment when the program needs it, not automatically at the programs' startup.

NumberFour
@NumberFour: Are you implying that unless I use delay load, I can't achieve what I want?
Armen Tsirunyan
@Armen: if you don't (or can't) delay load your library, then it will be a load-time dependency that gets loaded when your process is loaded. This will happen before any of your code executes, so you won't be able to call `SetDllDirectory` and the load will fail. If you don't need the functionality of the DLL right away (i.e. before `main`), then making it a delay-load dependency is fine.
Chris Schmich
@Chris: Ok, actually I don't need the functionality of dll before main, so I can add SetDllDirectory as the first statement in main, and everything will be fine. I get it, but what about a theoretical case when the functionality is needed before main? There is no way other than to put the dll in the same folder or to add the directory to PATH? That would be strange... I mean, there's BOUND to be a configuration property which I just can't find...
Armen Tsirunyan
@Armen: Beyond `LoadLibrary` and what you mentioned in your post, I don't think the Windows loader is all that configurable. I think it's pretty rare for a library to *have* to be a true load-time dependency, so there's not much need for making it highly configurable. Also, you can always set the `PATH` for *just your process* by using `GetEnvironmentVariable`/`SetEnvironmentVariable`. This way, you can modify the loader search path without requiring the user to do this and without affecting other processes.
Chris Schmich
@Chris: Oh, I never realized I could change Path only for MY process. Thanks a lot. I am accepting your answer :)
Armen Tsirunyan