0

I'm a beginner with building software using C++. In my project I link to DLLs and I keep them stored in the root folder. I do this because I want the project to be portable from one machine to another, and I also want the release builds to have dependence from installing things into system32 and what not.

The problem is all the DLLs in the root folder is messy, so I want to organize them into subfolders. But I can't do that because putting the DLL in a root subfolder instead of the root, you get errors. I think because the DLL is copied to the output at the wrong location, not where the exe is, but in a subfolder, just like the source structure. Am I right about that?

What is a solution that will allow me to have the project be still be copy-pastable/portable between machines?

Thomas
  • 6,032
  • 6
  • 41
  • 79

2 Answers2

4

Windows searches for DLLs in predefined locations (see Dynamic-Link Library Search Order). Subdirectories of the directory where the application resides are not part of the search order.

To implement your requirement, you will need to explicitly add the directories to the searched locations. This process consists of two steps:

  1. Call AddDllDirectory for each directory you want searched, in addition to the default search locations on application startup.
  2. By default, DLL imports are resolved prior to starting a process' primary thread. To allow your application to change the DLL search path, import resolution needs to be postponed. The easiest way to do this is by using the /DELAYLOAD (Delay Load Import) linker option (see Linker Support for Delay-Loaded DLLs for additional information).

While it is possible, to segregate DLLs into subdirectories, it is best to keep them all alongside the executable image.

IInspectable
  • 46,945
  • 8
  • 85
  • 181
2

If you put the DLLs into subfolders instead of keeping them in the same directory as the executable, you would either have to modify PATH environment variable in Windows to point to every subfolder, or use the DLLs in LoadLibrary+GetProcAddress way instead of linking them to the executable via import libs.

Community
  • 1
  • 1
Serge Rogatch
  • 13,865
  • 7
  • 86
  • 158
  • As an alternative to changing the global environment you can also pass an environment block into the [`CreateProcess`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw) call (e.g. from a launcher application). – IInspectable Dec 22 '22 at 08:11