C++ Moving DLL out of root directory into a subfolder, visual studio - c++

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?

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:
Call AddDllDirectory for each directory you want searched, in addition to the default search locations on application startup.
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.

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.

Related

Creating texture which is in project folder

I'm having trouble creating a texture which is in my DLL project's directory.
I'm doing
D3DXCreateTextureFromFile(Device, "Sprites/ExpandBlack.png", &BlackTexture);
but that doesn't seem to work. However if I do the whole path like:
D3DXCreateTextureFromFile(Device, "C:\\Users\\Home\\Documents\Visual Studio 2017\\Projects\\NO\\NO\\Sprites\\ExpandBlack.png", &BlackTexture);
it does work.
I also tried doing ../Sprites/ExpandBlack.png, ..\\Sprites\\ExpandBlack.png etc.
Any kind of help is appreciated.
This is where Sprites is located and it has to be "compiled" with the dll.
../Sprites/ExpandBlack.png, ..\\Sprites\\ExpandBlack.png and Sprites/ExpandBlack.png all refer to the same relative path.
Relative paths append to the process's working directory. DLLs use the same working directory.
To get a DLLs path see Get DLL path at runtime
Relative paths are relative to the current directory of the process. If it works when using a full path but doesn't work when using a relative path then obviously your relative path is not leading to where it should be leading. Most likely because the current directory of the process that's supposed to access that file is not what it should be.
Since we're talking about a DLL here, I suppose the problem is that when running the program that's actually using the DLL, that program is launched from a different location than the one the DLL project file is in. Most likely, because the project is located in a different directory than the DLL project. Visual Studio will by default use the directory in which the project file is located as the working directory for the process. You can change the working directory that Visual Studio will use in the project properties under "Debugging". Most likely, you will want your sprites located relative to the application that's using them rather than some DLL that the application is using. If these sprites are actually tied to the library and required by the library to function, on the other hand, then you may want to consider embedding the files into the library, e.g., as resources, or at least place these files relative to the library and access them based on the location of the DLL and not the current directory of the process that's using the DLL. To get the path of your DLL, see the answer linked in user2176127's answer…

Link qt dlls to multiple executables

I have four different .exes in differend subdirs of one specific directory. All of the programs need the exact same .dlls (Qt5Core, Qt5Gui and Qt5Widgets). Is there a way of having theese three .dlls just in the root directory insted of having to copy them into each subdirectory?
Here you find the order in which DLL paths are searched on Windows:
Since Safe DLL search mode is enabled by default, the order is
The directory from which the application loaded.
The system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
The current directory.
The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
So the easiest thing to do is to ensure that you run your app from the working directory where you put the DLLs (5.). That could be done by writing a starter .bat file that navigates there first and then runs the application relative to the DLL direcory.
The other way would be to add the DLL directory to PATH in a starter .bat file (6.).
In both cases you need a wrapper script for each .exe that you want to run.
You could avoid that if you can make sure that links to the application set the working directory properly. This would work if you have an installer creating the shortcuts for the user and you know the user will not create one himself by just right-clicking the .exe.
There might also be a way using hardlinks or junctions but I don't know if you can copy and deploy those like symbolic links on Linux or if you need to create them on the target system.
Yes, you are using Windows and you can add your root directory as a path in Environment Varibles from
Computer-> Properties->Advanced System Settings -> Environment Variables

How to add additional dll search directories for native unit tests?

I'm working on a big code base which has many solutions and many more projects.
When I write unit tests they often depend on a number of dlls being present which are built by other solutions into different output folders to my current solution.
I usually add build steps to copy required dll's to the current solution's output folder so that they can be found when I run unit tests. This can end up in a lot of wasted space and confusion with duplicate dlls and which is the master copy of each dll which is the one that should go into the installer.
Is there a better way of adding additional search directories?
I was considering having a TEST_MODULE_INITIALIZE that will AddDllDirectory() and then marking the dll's as delay loaded so that when they do load the added dll directory will be searched. But, I don't think that works as you have to mark the dll's as delay loaded in the exe. But, the exe is the testrunner which is out of my control.
Your consideration is absolutely right. You can load dependency dlls in VS testrunner context, as sure as a gun, in this way:
1) setup your test project to deploy all required dlls into output dir (for example with the help of pre\post-build steps)
2) set delay loading of dlls in test project settings. (Test project-properties-Linker-Input-Delay loaded dlls = enter list of dependency dlls)
3) Setup directory to search dlls. It could be either TEST_MODULE_INITIALIZE or TEST_CLASS_INITIALIZE. Simple case is to use SetDllDirectory for this purpose. If you want to use AddDllDirectory - use it carefully:
If SetDefaultDllDirectories is first called with LOAD_LIBRARY_SEARCH_USER_DIRS, directories specified with AddDllDirectory are added to the process DLL search path. Otherwise, directories specified with the AddDllDirectory function are used only for LoadLibraryEx function calls that specify LOAD_LIBRARY_SEARCH_USER_DIRS.
It may not be the best method, but since you're using Visual Studio 2013, you should look into test settings to control what is deployed when you run your tests. Inside of test settings you can specify files or folders in the Deployment section which will allow you to select files outside of your current solution. You can create multiple test settings (one for local and one to use on a build server if the paths to these files are going to be different).
Again, maybe not the best solution, but it has worked for me in the past.
Specifying Test Settings for Visual Studio Tests -
https://msdn.microsoft.com/en-us/library/ee256991.aspx

Where to place and how to include dll files in c++ project?

I read this guide that walks you through the steps necessary to create a "visual" application with Cairo and Visual C++. The guide suggests you download certain dll files and store them in the directory in which your executable is created (debug).
Here is the list of the files Nil is referring to in his tutorial:
cairo Binaries (yes you need the binaries package too, as the Dev one doesn't contain the DLL) -> libcairo-2.dll
zlib Binaries -> zlib1.dll
libpng Binaries -> libpng12-0.dll
Freetype Binaries -> freetype6.dll
FontConfig Binaries -> libfontconfig-1.dll
expat Binaries -> libexpat-1.dll
As you can see, it's quite a lot of files. I've been wondering if this the "correct" way of doing this? Is there an alternative way that is considered "best-practice" in this case?
There's nothing wrong with this approach, and it's probably the quickest way to get your application up and running. Your application needs these libraries, so putting them in the same folder allows it to find them.
There are of course always alternatives!
Static linking
To avoid having a bunch of dlls that have to exist with your application, you could use static linking. You link the .lib files at link-time rather than linking to the .dll files at run-time. Makes your .exe larger, but means you may be able to distribute a single file.
Placing Dlls in a different folder
The dlls do not have to be in the same folder as the .exe, though that normally makes the most sense. Windows will search several folders when looking for a .dll at run-time, so you could put the dlls in the current directory, a system directory (definitely not recommended), or another directory in your PATH environment variable. Actually none of those locations are recommended! Putting them in the same folder as the .exe is the safest, because generally you have control of that folder.
The specific rules for how Windows searches for a .dll are outlined here: http://msdn.microsoft.com/en-ca/library/windows/desktop/ms682586(v=vs.85).aspx
Custom Build Step
I don't like manually putting files in my debug or release folders. I like to think of the debug folder as something I can blow away and rebuild at any time, and I like to have a one-step build process that puts everything where it needs to be so I can easily build on any machine. So I will usually create a custom build step that copies the required .dlls from a "source" folder (in source control) into my output folder.

Infernal Libraries (aka DLL Hell)

In a Project of mine, I use a Delphi Application which dynamically loads a wrapper DLL (exporting C-Style functions) which in turn is statically link against a bunch of 3rd party DLLs.
It works fine on my test machines, but on my customers computer it failed to initialize with an error Message like "Couldn't find entrypoint _somefunction#4AKKZ in TMYlibrary.dll".
After some investigation with sysinternal's process monitor, I realized that Windows would look fror DLLs in windows/sytem32 first, so if a DLL named similar to my DLL was present in system32, windows would pick that one and try to find my function entry points in it - which would fail.
Do you know of a possiblity to change windows' DLL the searching behaviour?
Additional Information
[Update] The .exe file is located on the top level of the application's folder tree.
The Wrapper and the 3rd-party-DLLs ar e both located in the Subfolder /bin of my apps Folder
Dev platform is windows XP/7, using VS2008 for the dlll and Delphi 2010 for the application
I found another solution myself:
SetDllDirectory adds an additional search path to the list of locations to look at.
From http://msdn.microsoft.com/en-us/library/ms686203%28v=VS.85%29.aspx
After calling SetDllDirectory, the DLL search path is:
The directory from which the application loaded.
The directory specified by the lpPathName parameter.
The system directory. Use the GetSystemDirectory function to get the
path of this directory. The name of
this directory is System32.
The 16-bit system directory. There is no function that obtains the
path of this directory, but it is
searched. The name of this directory
is System.
The Windows directory. Use the GetWindowsDirectory function to get
the path of this directory.
The directories that are listed in the PATH environment variable.
(maybe i should do my googling before I post on SO ;)
Ship the DLL in your program's folder. (same as the exe file).
Then Windows should try your version first.