including library and dll into c++ project - c++

I have a third party library (say, tp.lib) and the third party dll (say, tp.dll) which I need to use in my C++ project (my project makes a dll, lets call it my.dll).
I have included the library with the #pragma comment(lib, "libraryname") in the header file
and also included the path of the library file in the configurationproperties->linker->additional library directories in my C++ Visual Studio project.
The code compiles and links okay. but fails to execute. When I used depends to check if i am missing something, I observed that the tp.dll is not found. The tp.dll resides in the same library folder where the tp.lib resides.
What should I do so that tp.dll gets included to my.dll?

DLLs have a different search path. Quote below from docs:
With both implicit and explicit linking, Windows first searches for "known DLLs", such as Kernel32.dll and User32.dll. Windows then searches for the DLLs in the following sequence:
The directory where the executable module for the current process is located.
The current directory.
The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.
The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.
The directories listed in the PATH environment variable.
Note
The LIBPATH environment variable is not used.

The search path at runtime does not include the folder where you put the lib library, so putting the DLL with the lib is not enabling the OS to find it at runtime. You can add that to the path, or move the DLL. The list of search precedence is on MSDN.

You can't "include the dll into another dll". You need to either deploy them together, or put the dependency dll in a place where Windows will find it.

Related

SDL2.dll was not found

I'm trying to set up SDL2 in C++ Visual Studio but when I run the code(just some starter code I copied) it pops up with an error box box that talks about "SDL2.dll cannot be found" I tried switching to x64 but that was no help. I can see that the dll is right next to the lib files but it just won't work.
Your problem is the lib folder is not a place that your OS will search for dependent dlls by default. To fix this you would have to help your OS find the dll. There are several methods you can use to tell your OS where to look. One is adding an entry to your PATH environment variable that contains the full path to the folder containing the dll.
This site can help with setting the PATH: https://www.computerhope.com/issues/ch000549.htm
As second method is to put the dll in the same folder as the executable.
By default your OS probably is using the safe search option described here:
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.***

On windows is it possible to get dll's to look for dependencies in another folder without using the PATH environment variable?

On linux I am able to set theRPATH of a shared library to $ORIGIN:$ORIGIN../lib. This tells the DLL to look in the same directory as the shared library as well as in the ../lib folder. I've read that on windows you just add the absolute path to ../lib (for example) to the PATH. Is there an alternative to this method? I want my dll to look in the ../lib folder but don't really want it on the path. Is this possible?
If the main DLL dynamic/delay-loads the dependent DLLs, it can call SetDllDirectory() (or better, AddDllDirectory()) before loading them.
If the main DLL static-links to the dependent DLLs, but the EXE dynamic/delay-loads the main DLL, then the EXE can call (Add|Set)DllDirectory() before loading the main DLL.
Otherwise, you will have to either:
update the %PATH% environment variable.
use an application manifest that specifies the paths of the dependent DLLs.
use DLL Redirection.

How to include dll as relative path?

I have a dll in my project which I am referring through absolute path(C:\test\something\abc.dll) to load in my project. How do load it relatively or is there is better way to include it in visual studio project?
MSDN::
Before the system searches for a DLL, it checks the following:
If a DLL with the same module name is already loaded in memory, the system
uses the loaded DLL, no matter which directory it is in. The system
does not search for the DLL.
If the DLL is on the list of known DLLs
for the version of Windows on which the application is running, the
system uses its copy of the known DLL (and the known DLL's dependent
DLLs, if any). The system does not search for the DLL. For a list of
known DLLs on the current system, see the following registry key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session
Manager\KnownDLLs.
The standard searching order for Dlls is::
The directory from which the application loaded.
The current directory.
The system directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory.
The directories that are listed in the PATH environment variable.
You can always have your Dll with the application in the same directory. Carrying it as resource within application is not advisable.
You can specify dll name without path and place the dll in the same directory where the executable loading it resides, or in the current directory (the one from which you launch the program).

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.

How do I use a third-party DLL file in Visual Studio C++?

I understand that I need to use LoadLibrary(). But what other steps do I need to take in order to use a third-party DLL file?
I simply jumped into C++ and this is the only part that I do not get (as a Java programmer). I am just looking into how I can use a Qt Library and tesseract-ocr, yet the process makes no sense to me and is so difficult to google.
How do I tell the compiler of the functions that I am using? Should there be an include file from the third-party vendor?
As everyone else says, LoadLibrary is the hard way to do it, and is hardly ever necessary.
The DLL should have come with a .lib file for linking, and one or more header files to #include into your sources. The header files will define the classes and function prototypes that you can use from the DLL. You will need this even if you use LoadLibrary.
To link with the library, you might have to add the .lib file to the project configuration under Linker/Input/Additional Dependencies.
To incorporate third-party DLLs into my VS 2008 C++ project I did the following (you should be able to translate into 2010, 2012 etc.)...
I put the header files in my solution with my other header files, made changes to my code to call the DLLs' functions (otherwise why would we do all this?). :^) Then I changed the build to link the LIB code into my EXE, to copy the DLLs into place, and to clean them up when I did a 'clean' - I explain these changes below.
Suppose you have 2 third-party DLLs, A.DLL and B.DLL, and you have a stub LIB file for each (A.LIB and B.LIB) and header files (A.H and B.H).
Create a "lib" directory under your solution directory, e.g. using Windows Explorer.
Copy your third-party .LIB and .DLL files into this directory
(You'll have to make the next set of changes once for each source build target that you use (Debug, Release).)
Make your EXE dependent on the LIB files
Go to Configuration Properties -> Linker -> Input -> Additional Dependencies, and list your .LIB files there one at a time, separated by spaces: A.LIB B.LIB
Go to Configuration Properties -> General -> Additional Library Directories, and add your "lib" directory to any you have there already. Entries are separated by semicolons. For example, if you already had $(SolutionDir)fodder there, you change it to $(SolutionDir)fodder;$(SolutionDir)lib to add "lib".
Force the DLLs to get copied to the output directory
Go to Configuration Properties -> Build Events -> Post-Build Event
Put the following in for Command Line (for the switch meanings, see "XCOPY /?" in a DOS window):
XCOPY "$(SolutionDir)"\lib\*.DLL "$(TargetDir)" /D /K /Y
You can put something like this for Description:
Copy DLLs to Target Directory
Excluded From Build should be No.
Click OK.
Tell VS to clean up the DLLs when it cleans up an output folder:
Go to Configuration Properties -> General -> Extensions to Delete on Clean, and click on "..."; add *.dll to the end of the list and click OK.
These are two ways of using a DLL file in Windows:
There is a stub library (.lib) with associated header files. When you link your executable with the lib-file it will automatically load the DLL file when starting the program.
Loading the DLL manually. This is typically what you want to do if you are developing a plugin system where there are many DLL files implementing a common interface. Check out the documentation for LoadLibrary and GetProcAddress for more information on this.
For Qt I would suspect there are headers and a static library available that you can include and link in your project.
In order to use Qt with dynamic linking you have to specify the lib files (usually qtmaind.lib, QtCored4.lib and QtGuid4.lib for the "Debug" configration) in
Properties » Linker » Input » Additional Dependencies.
You also have to specify the path where the libs are, namely in
Properties » Linker » General » Additional Library Directories.
And you need to make the corresponding .dlls are accessible at runtime, by either storing them in the same folder as your .exe or in a folder that is on your path.
You only need to use LoadLibrary if you want to late bind and only resolve the imported functions at runtime. The easiest way to use a third party dll is to link against a .lib.
In reply to your edit:
Yes, the third party API should consist of a dll and/or a lib that contain the implementation and header files that declares the required types. You need to know the type definitions whichever method you use - for LoadLibrary you'll need to define function pointers, so you could just as easily write your own header file instead. Basically, you only need to use LoadLibrary if you want late binding. One valid reason for this would be if you aren't sure if the dll will be available on the target PC.
I'f you're suppsed to be able to use it, then 3rd-party library should have a *.lib file as well as a *.dll file. You simply need to add the *.lib to the list of input file in your project's 'Linker' options.
This *.lib file isn't necessarily a 'static' library (which contains code): instead a *.lib can be just a file that links your executable to the DLL.