0

I'm loading a DLL in an application. If I have the full path hardcoded in the program, it looks like this:

LPCWSTR dllPath = L"C:\\MyLibs\\PernumLib.dll";
HINSTANCE hinstDLL = LoadLibraryW(dllPath);

I've modified the code to:

LPCWSTR dllPath = L"PernumLib.dll";
HINSTANCE hinstDLL = LoadLibraryW(dllPath);

It works as long as the DLL is either in C:\Windows\System32 or in the same folder as the exe file. But I want to link the DLL from C:\MyLibs. I tried the parameter Properties->Linker->General->Additional Library Directory, but it apparently doesn't define the search path for LoadLibraryW(). There are quite a few configurable directories under Properties->Configuration Properties->VC++ Directories, but they don't apply either. I've tried basically every directory I've found in Visual Studio Properties without success.

I know I can use the function SetDllDirectoryW() in the code, and it works. But it is another form of hardcoding.

Is there any way to configure the search path for LoadLibraryW() in Visual Studio?

Kalle Svensson
  • 353
  • 1
  • 10
  • Are you hoping that by changing some kind of build settings in Visual Studio, it would be possible to cause the compiler to somehow automatically insert a call to `SetDllDirectoryW` with the specified path, before everything else? – heap underrun Mar 25 '23 at 19:23
  • Or are you hoping there is some kind of a manifest possible to be embedded in the executable (or perhaps in a separate file) that would affect the [dynamic-link library redirection](https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-redirection), similarly to what `application.local` does, but that will set a specific path you'll specify in Visual Studio settings? – heap underrun Mar 25 '23 at 19:28
  • @heap underrun: When the application is released, I can place the DLL in the exefile folder. But as long as I'm using VS, I want to configure from where the DLL is fetched. It means that it would be enough to use an environment variable. I'm not sure if there is any and how to set it in VS. There may be other options, of course. – Kalle Svensson Mar 25 '23 at 19:56
  • 2
    If the DLL will be copied to the exefile folder in the release, why can't you place it there for debugging, too? Just create a post-build step that copies the DLL to the output folder. – PMF Mar 25 '23 at 20:45
  • 1
    I just make sure that there's a copy of the DLL in the .exe folder. Also, I load it using an absolute path derived from `GetModuleFileName (nullptr)` – Paul Sanders Mar 25 '23 at 21:07
  • 1
    DLLs are searched for on `PATH`, in addition to other places. For debugging purposes, you could adjust `PATH` variable under Properties > Debugging > Environment – Igor Tandetnik Mar 25 '23 at 21:41
  • @IgorTandetnik Only trouble with that is, if there is more than one version floating about, you might load the wrong one. Fun and games debugging that! – Paul Sanders Mar 25 '23 at 22:23
  • I consider copying the DLL between directories an inconvenient and unsafe solution. Moreover, while working in VS I modify the DLL frequently and maintain several versions in different places. I would like to select and load a DLL without making changes to the code. Using `PATH` sounds like a good alternative, but I'd like to do it in VS, not in Windows. – Kalle Svensson Mar 25 '23 at 22:25
  • @Paul Sanders: It has happened already. But I can add a MessageBox, popping up once and telling what version is used. – Kalle Svensson Mar 25 '23 at 22:29
  • 1
    Again, within Visual Studio, under Properties > Debugging > Environment, you can set up environment variables that are in effect during the debugging session. Is this not "in VS" enough? – Igor Tandetnik Mar 26 '23 at 04:42
  • 1
    If you are worried about multiple versions load it explicitly with an absolute path. Then again, how are those other versions going to be found unless your path env var is a mess? Why don't you put the exe and dll projects in the same solution and output the two files to the same folder? I think you know all the possible options. Pick one. – David Heffernan Mar 26 '23 at 04:55
  • @David Heffernan: Put the exe and dll projects in the same solution?? I thought a project was the solution and you could have one target, either exe or DLL in the project. Or can you have both? Or can you make "a solution" of two projects? How? What is "the solution? – Kalle Svensson Mar 26 '23 at 08:13
  • @PMF: Can you add a post-build step in VS? So that when I press F5, the target is built and a copy operation is executed? – Kalle Svensson Mar 26 '23 at 08:36
  • Yes you can have multiple projects in a solution. A solution is a container of one or more projects. – David Heffernan Mar 26 '23 at 08:58
  • @David Heffernan: Thank you, David, but could you give me a hint where I can read how to create a solution container? – Kalle Svensson Mar 26 '23 at 09:04
  • The visual studio documentation is where I would look. Or a basic websearch which still works even with the advent of stack overflow. – David Heffernan Mar 26 '23 at 09:22
  • @Igor Tandetnik: Yes, I added `PATH=C:\etc...` and the DLL is found and loaded. Thank you! In fact, this is the solution I was looking for. – Kalle Svensson Mar 26 '23 at 10:59
  • @David Heffernan: I've tested it. DLL is now placed next to exe, good! But build **sometimes** doesn't notice changes in the DLL source. To be on the safe side, you have to rebuild the DLL separately in the solution pane. Thank you for this fine hint! – Kalle Svensson Mar 26 '23 at 11:24
  • 1
    Once you have a solution wit two projects, make the EXE project depend on the DLL project. In the menu, choose [Project > Project dependencies](https://learn.microsoft.com/en-us/visualstudio/ide/how-to-create-and-remove-project-dependencies). Then the build system would check that both EXE and DLL projects are up to date, before running the EXE. – Igor Tandetnik Mar 26 '23 at 13:59
  • @Igor Tandetnik: I'll try this. I think you could make the answer from the PATH proposal. It may be evident to you but it wasn't for other commentators and for me so it is worth the answer. It does solve my problem, I'll accept it. – Kalle Svensson Mar 26 '23 at 16:02
  • [\[SO\]: Can't import dll module in Python (@CristiFati's answer)](https://stackoverflow.com/a/59333711/4788546) is the same, but has the extra *Python* layer. Or [\[SO\]: Discover missing module using command-line ("DLL load failed" error) (@CristiFati's answer)](https://stackoverflow.com/a/74883130/4788546), [\[SO\]: Load a DLL with dependencies in Python (@CristiFati's answer)](https://stackoverflow.com/a/61776284/4788546). – CristiFati Mar 28 '23 at 14:41
  • @CristiFati: This question is quite different. I'm looking for a `Visual Studio` setup, nothing else. The other guy is looking for a `command-line solution`. I **know** how to load the DLL, but I want to avoid a hardcoded path in the source code. He doesn't even know the name of the DLL. A different problem. And `my problem has been solved`; only the answer is missing. – Kalle Svensson Mar 30 '23 at 08:59
  • I know, I've read the comments. The answers I pointed out include the solution (setting *PATH*), but also offer more context on **why** doing so. The *PATH* setting should also be applied when running (debugging) your *app* in *VStudio*, and here [\[SO\]: How to include OpenSSL in Visual Studio (@CristiFati's answer)](https://stackoverflow.com/a/32158521/4788546) (section ***#3.***) covers precisely this topic. – CristiFati Mar 30 '23 at 09:50

1 Answers1

0

The solution is given in the comment by Igor Tandetnik. The directory search in LoadLibraryW() uses the environment variable PATH (Windows uses Path). It may be set in Properties->Debugging->Environment, e.g., PATH=C:\MyLibs.

A different approach is proposed by David Heffernan. In the VS Solution pane, you can add the DLL project to the main project. Then, building places the DLL in the exe folder. Also, in the Solution pane, right-click the main project and add a dependency from main to the DLL to ensure that the DLL is rebuilt when its source changes.

Kalle Svensson
  • 353
  • 1
  • 10