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
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 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 planning to use id3lib in my application. I'm looking for a way to use the library as a DLL. I've noticed that they released the library in various form: one of which is windows binary. My target platform in Windows, and I'll use Qt 4.8. After I extract the files in windows binary, I found the following files in Release folder:
id3lib.dll
id3lib.exp
id3lib.lib
I know how to use a DLL in Qt given the DLL, one or more header files where function prototypes resides, and with or without the *.lib file. This package doesn't come with a header file.
How am I supposed to use this package without any header file? What's the purpose of the *.lib and *.exp files here? As far as I know *.lib files are used for static linking with functions which I don't want in my program.
You've just missed the header. It is available under the include subfolder (see here), also the .lib file is still needed for linking, even if you'll be using the DLL.
The usual course is to use a header file #included in the C++ file, the .lib file to link to and the .dll is required at run time.
The header file should/may be in another package as the same header is probably used for different kinds of linking strategies.
At worst you should be able to use a tool such as depends.exe to view the exported symbols and create your own h file to match - but it would be better to find a .h file issued with the release.
I followed the MSDN walkthrough on creating and using a DLL in Visual C++ Studio, but it requires the user to add the DLL project to the same solution as the project they're working on.
Is there a simple way to include a DLL? Ideally, I'd like to just distribute my .dll (and the .lib, I suppose) to my friends so they can use it in their own projects.
I realize there are other walkthroughs out there (some of them on SO), but they all require editing the PATH environment variable, etc. Is that really the simplest way?
At a minimum, you need to do the following:
Include the .lib file in the project
Tell the linker where you put the .lib file (library search path)
Make the .dll file available at runtime (easiest is to put it in the same directory as the .exe)
To distribute the compiled .dll to your friends, you will need to include:
the .h file(s) for the compiler
the .lib file for the linker
the .dll file for runtime
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