I'm new to C++ and there's something I just completely don't get. In C#, if I want to use an external library, log4net for example, I just add a reference to the log4net DLL and its members are automatically available to me (and in IntelliSense). How do I do that in non-managed C++?
Often, the library comes with 1) a header file (.h) and 2) a .lib file in addition to the .dll.
The header file is #include'ed in your code, to give you access to the type and function declarations in the library.
The .lib is linked into your application (project properties -> linker -> input, additional dependencies).
The .lib file usually contains simple stubs that automatically load the dll and forward function calls to it.
If you don't have a .lib file, you'll instead have to use the LoadLibrary function to dynamically load the DLL.
The basic concept is the following:
There are 2 types of libraries: static & dynamic. The difference between them is that static libraries, during the linking build step, embed their compiled code in your executable (or dll); dynamic libs just embed pointers to the functions and instructions that some dll should be loaded when program is going to be loaded. This is realized for you by the linker.
Now you can decide which of those two you are going to use. DLLs have many advantages and disadvantages. If developing a huge application it might be worthy to consider using DLLs with delay loading instead of static lib's. Some libs are simply delivered to you as DLLs and you have no choice. Anyway the easiest way for a beginner would be to use static libraries. That would make your deployment and test much easier, since, when dealing with DLL you have to ensure that they are found at runtime (even when using debugger), this involves either copying everything in one directory or dealing with path variables.
Usually a DLL provider (if it is intended that you should be able to deal with the library) delivers you a header file(s) and a .lib which contains the calls into the desired DLL. Some vendors (e.g. boost) only require you to include the header file and the lib is automatically linked to your executable (can be achieved through compiler prorietary pragma directive). If it is not the case you must go into the project settings of the C++ project (project properties/Configuration Properties/Linker/Input) and enter the lib file name into the "Additional Dependencies" row, e.g. iced.lib; iceutild.lib. You can also put fully qualified path names there. Be aware that you have to enter the lib file names for both configurations (Debug, Release). This is the procedure you do with static libraries and Dll equally. The only difference that DLL will require a DLL lib to be either in you app-directory or in one of the path-directories.
After that step, you still might get compiler errors if you try to link incompatible libraries. There are many reasons, why they can be incompatible. But try to first link the lib this way and see if works. If not, post again your errors here ;)
Include file(s) is(are) used to be included in places, where you would like to use smth. from the lib. Just include it and the compiler will know that the symbols must come either from another (compiled) compilation unit (compiled cpp-file=>object file) or the .lib. It will make the look up and notify you if the required symbols are not found.
Good Luck,
Ovanes
P.S. This might be hard in the beginning, but when you get used to it, it will be easy.
C++ doesn't have libraries in the sense you're thinking of. It has header files that you #include, and it has things called libraries that the linker deals with, which contain the compiled code. You need to add the libraries (.LIB files) to the linker settings.
On Windows if you're using a DLL, ideally you should have a .LIB file to go with it that is called the Import Library for the DLL, and you add that .LIB file to your linker settings.
The first thing you need to do is to #include the header file that describes the functions that are available in that library.
The actual code for the library will be in one of 2 places:
A static library (.lib)
A dll (.dll)
Depending on how the library's code is given to you (as .lib files, or as a .dll), you'll have to either:
#pragma comment( lib, "libraryname.lib" ) if its a .lib
LoadLibrary if its a .dll
Sometimes a package comes with BOTH a .lib file that you need to link to, and a .dll file. In this case you don't need to call LoadLibrary, you only need to #pragma comment( lib, "libaryfile.lib" ) because in this case the .lib links you into the .dll.
A very important detail is to put the DLL where your application can find it. Charles Petzold says:
When Windows needs to load a DLL module before running a program that requires it, the library file must be stored in the directory containing the .EXE program, the current directory, the Windows system directory, the Windows directory, or a directory accessible through the PATH string in the MS-DOS environment. (The directories are searched in that order.)
Programming windows, 5th ed
MSDN
I don't recommend using the project properties menu to link because it isn't as visible what libraries you're linking to.
See also
Related
I have some confusion about static and dynamic linked libraries and .lib and .dll files.
I have a project with two libraries, one I built myself and one is from an open source library.
The one I built myself is a separate project in the same solution (Visual Studio 2015, C++), and I don't need to copy over the .lib files or create a DLL for the executable to build and run
For the other open source library, I do need to copy over the .lib file and the DLL into the executable folder. However, I thought it would be possible to statically link a .lib file and not have to copy over the DLL.
Does this mean I need to compile the Open Source library differently? Like change the define __declspec(dllexport) to __declspec(dllimport) ? Or change /mD to /mT in compiler options?
I tried both of these, but it's still saying that it can't start without the .dll
Or can I get away with changing a setting in the executable project to link this library statically? If so, what are these settings?
EDIT: I know this is a standard question that can be looked up on google, but I haven't been able to find an exact answer for a while. Mainly, I'm confused about what settings need to be changed, and which project they need to be changed in. (The library or the executable).
I'm under assumption that static linking means the library is built into the executable, and dynamic linking means the library needs to be in a separate file, if this is incorrect, please let me know. Otherwise, I need to know how to build the library into the executable file.
And I can go ahead and change the build options in the open source library, and I tried this already.
Thanks,
-D
In Windows, dll files (dynamically linked libraries) need to be in the same directory as the application or on the search path. lib files (static libraries) need to be statically linked during linking (the last step of building the application). It's common in Windows so have a library come with both a dll and lib file. In this case, the lib file is an import library containing the information needed to easily link to the dll.
Place the dll file where your application will be built and statically link with the lib file. Go to 'Project->Properties->Link->Input->Additional Dependencies' and 'Project->Properties->Link->General->Additional Library Directories' to specify the static libraries you want to link.
Edit: It seems I misunderstood the question. The question is how to recompile a dynamic library as a static library. You need the source code of the library you are using along with it's Visual Studio Project file. Open the library and in `Project->Properties->General->Configuration Type' change it from Dynamic Library to Static Library.
Beware that Dynamic Library uses the Linker group of properties while the Static Library uses the Librarian group of properties. Changing between these types may cause the project to drop essential linker flags options. Since every library is different, I can't predict what you will have to do work around this. Make sure to backup the project file so you can see the original options and flags.
I had to change the setting for "Static Library" for All Configurations, not just Debug, although it was building in Debug. Not sure what may have caused this. Possibly because the debug and release builds for the library were set to the same folder, it may have been overwriting the debug builds with release builds when building
I am building a dll project. I am using openssl and quickfix libraries. I don't want users to separately copy the libraries when they use dll. I want to bundle these .lib files into my dll as well.
I am using visual studio. How can I bundle these libraries(.lib static libraries) into my dll so that the user can just copy my dll into their projects and start working right away.
Thanks,
by default it'll be bunded in. you program, just call it MyProgram.DLL, can
call other programs, as a DLL file, e.g. C Runtime Library provides
MSVCRT.DLL for MyProgram.DLL to call; or
include other program's Static Library file, i.e. the .LIB files, inside your binary, i.e. MyProgram.DLL, e.g. C Runtime Library provides LIBCMT.LIB for MyProgram.DLL to include inside and call.
It seems you want option 2), but actually, since what provided are .LIB files, option 1) is not possible for you.
I was thinking: when I produce a DLL with Visual Studio (C++) it generates
a .dll file
a .lib file
And I have a .h file
So, why not developing directly a static .lib library?
For example, why Office doesn't have .lib files?
And, in the future, if I change the DLL, will I have to send to all the machines also the new .lib file and .h file?
The .h and .lib is only for developers. Whoever writes a program to use the DLL.
Those who just execute the application need only the .DLL.
So if you release a new version, you send DLL to users and the triplet to developers. Unless you changed the public interface (the exports), the old clients will be happy to use the updated DLL without any work.
If you instead build a static .lib, every client must rebuild his binaries.
The .lib file and the header file is the static part of your dynamic library.
You need the .lib and header file in order to compile and link a program so that it uses your library.
So why not use a static library?
There are multiple reasons. One would be that if you use a static library every change of your library causes a recompile of your program. Another that the size of your program will increase. And some more.
So for your second question the lib file are useless for a user of your program. In case of office. As long as you don't have the sources and a compiler the lib files will not help.
For your last question. The answer is also simple. No you don't need to distribute the .lib files. You can replace the dll files with new versions as long as the interface stays the same.
This is a SHORT version that tries to answer your specific questions. The subject of "how DLL's and shared libraries work" is quite a few pages long, and I'm just not going to write that all as an answer.
To start with the parts the compiler generats, a .lib and a .dll file, are used as follows: The .lib file contains "stubs" that go into .exe file using the .dll, and contain "where to find the different functions" in the .dll file. So this is used only when building the .exe file. Similarly, the .h file is used when compiling the .dll and .exe file, and aren't used once you have the final binaries (.exe and .dll files) that make up the product.
The purpose of using DLL's over static linking is most important when there are multiple executables that use the same .dll file. If there is only one "user" of a DLL then the the benefits are reduces, but there are still some benefits (such as compartmentalisation, ability to supply updates to only that part of the code, plugins, etc).
Assuming your .dll is part of a program that contains only binaries, no source code, then you only need to distribute the new .dll [as long as the functions haven't changed in such a way that the .exe or other .dll's that use this .dll has to change, of course].
I'm trying to start a C++ game engine project.
I don't have much knowledge of dll's and lib's but figured the engine itself would be a dll and I would have separate dll projects such as renderer, input, etc that would be used by the engine and the engine dll would be used by the game.
I seem to have the engine project referenced fine in the demo.exe project(by adding a reference and adding the path to additional include directories) but when trying to add a reference to a renderer dll project in the engine dll project I'm getting:
error LNK1104: cannot open file 'MyPath\Renderer.lib' MyPath\LINK
Engine
Why is it mentioning libs?
Many DLLs comes with corresponding LIB libraries, that are only needed at linking stage. So basically there are 2 types of LIB libraries:
Real static library that contains all the object files
Library with only definitions for the linker, this kind of libraries comes with DLLs
So basically you need to link this LIB file in order to be able to work with DLL
So I sorted my problem. As they were new projects they had no methods implemented yet, so no lib was being created, so nothing to reference to..silly me.
One last thing though, I'm having trouble defining the dllimport/dllexport macro for a header file. I'm trying to get it to define dllexport when its the exporting project but say my project is 2 names, e.g "awesome engine" then how do I realise the export macro that apparently is created automatically? Should I use an underscore for the space?
#ifdef AWESOME_ENGINE_EXPORTS // Or AWESOMEENGINE_EXPORTS?
#define DLL __declspec(dllexport)
#else
#define DLL __declspec(dllimport)
#endif
the engine project referenced fine in the demo.exe project(by adding a reference and adding the path to additional include directories)
Some libraries can be linked statically, meaning that you need only header files (.h/.hpp) and .lib files. Other libraries might require dynamic linkage that will result into your program being dependent on some DLL files, but usually you will need to have header files to know what is in those DLLs anyway. Sometimes, which seems to be your case, you need all of them: header files, static libraries and DLLs.
Header files contain declarations, they define the structure of your classes, they declare prototypes of your functions, etc. Static libraries (.lib files) are binaries, that contain definitions of your functions, variables and so on, that need to be resolved at compile time, so when they are missing, the linker will complain. Dynamically linked libraries (DLLs) are binaries as well, but they are resolved at run-time, meaning that the time when you really need them is when you run your program.
Generally,
The library may give you it's APIs in two modes:
Dynamic: Smaller executable file, but needs its DLLs.
Static: Larger executable file, but stand-alone.
First of all, decide how do you want to use that library, statically or dynamically?! Then configure your project which the compiler be able to find header files of that library.
Then if it's necessary add LIB files to your project.
In your case: Check if you added LIB files correctly to your project or makefile, or not?
This question might seem obvious but I am having a lot of trouble with this, and I have ended up having to post here after a lot of searching.
I currently have two windows of Visual Studio open. One is a Win32 Console->DLL project which exports a class, and in the output directory I have:
.dll file
.exp file
.pdb file
.lib file
I have dropped the DLL file into the my other project's output directory, as I do with all DLLs, and that works fine usually. Then, I added the directory into the Linker's library directories.
But unlike most libraries I use, I think I have done something wrong or I misunderstand how this works, I have no .h[pp] files, and so I have no idea how I am supposed to include the functions into my code. I'd rather not have Windows-only hacks (I want to confine that to the DLL project only, so that it can be ported easily).
Can anyone enlighten me as to what I am doing wrong?
There is nothing 'hacky' or 'windows' specific about having .h files available to the other projects. Your .lib file will provide the necessary information to complete the build. See: How do I use a third party dll in Visual Studio C++?
Did you add the .lib file corresponding to the .dll into the other project's directory?
It is the .lib file that is consumed by the linker, not the DLL (which is consumed by the loader at run-time).
A .dll is a shared library, as opposed to a static library (.lib on Windows).
Static library must always be linked when you compile your project, and you can easily call their functions using header (.h/.hpp) files, whereas you have two options for the shared library:
static linking (at compile-time, but the way to do it is different than for a static library)
dynamic linking (at run-time)
I would advise you to read this in-depth article: http://www.codeproject.com/Articles/85391/Microsoft-Visual-C-Static-and-Dynamic-Libraries
See also the wikipedia article: https://en.wikipedia.org/wiki/Dynamic-link_library