Qt non-static linking and .pro files - c++

I am trying to build a .dll that uses the QtCore4 and QtGui4 .dll files. However, I want both Qt .dll files to be linked non-statically. I have read a lot about .pro files and static linking but no one seems to talk about dynamic linking with Qt .dll's. How do I ensure that the qt dlls are built for dynamic linking?
I am having problems that there seems to be two instances of the dll's in my app, one in the app that uses my dll, and then one for the dll itself, so when I try and get a window handle the code inside my dll can't 'see' it; disjoint qtwidget sets is the phrase often used.
Any suggestions?

Unless you added the keyword 'static' to your configuration parameters, the Qt libraries should be already building as dynamic link libraries. That is the default configuration.

The dll extension means Dynamically Linked Library. This means that if you compile the library as a dll, it will always be suitable for dynamic linking.
(If you build a library for statical linking, that has a different extension and requires different config.)
In Qt projects, dynamic linking is the default option. You don't need to do anything to achieve it.

Related

Are lib files exclusively statically linked or do they need to be compiled specifically (VS2015)

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

Is there any way to make a Qt DLL that statically links to the Qt runtimes?

I have written a DLL in Qt. If I try to statically build it (so that you don't need Qt installed in order to use the DLL), it becomes a .lib file. Is there any way to statically build the DLL file without making it a .lib file?
I have two Qt installations. The non-static one creates a DLL file but the static one creates a LIB file.
You need to make sure that your Qt installation is statically built in order to link statically. I would check the Qt license for linking statically though as you may have to open source your project in order to legally link Qt statically in accordance with LGPL.
You want to build a dynamically linked library with dependencies statically linked.
You library will be compiled to be a DLL, but the Qt dependency needs to be statically linked against your library.

add two dll's to msvc 2010 application

I'm trying to use libcurl library in my application.
when i start my application, it asks for libcurl.dll and zlib1.dll
to exist in the same folder. when i add them everything works fine but i want to include
them to the executable.
how can i statically add both dll's to the application?
You cannot statically link dlls into an executable. The purpose of dynamic libraries is to be loaded dynamically during runtime from an external image (dll file). You should check whether curl and zlib provide proper static libraries and link against them instead of lib stubs for the dlls.
Consider that linking against static external libraries makes your binary potentially vulnerable against any security issues in statically linked blobs. That means that you will have to update any binary you statically linked against those libraries instead of simply updating the libraries themselves.

Compiling a static lib inside a exe

I have a dll and an exe, both of which I have the sources to.
For the DLL I have compiled completely statically and therefore, I would assume that the the .lib is also static. However, when I include that lib in my C++ VC++ 2008 project under Linker > Input > Additional Dependencies . I set the compile mode to /MT (multi-threaded) for the exe.
Everything compiles, but when I try to run the exe, it asks for the dll! To the best of my (limited) understanding, that shouldn't be happening.
Why should I do?
The 'compile mode' setting that you are referring to is the setting for the runtime library that gets linked with whatever library or executable you produce.
If your project is set up to produce a DLL (check the main project page), then it'll still produce a DLL no matter what you're putting into the runtime library setting. What I think you want to do is change the setting on the DLL's main project page from DLL to Static Library instead of changing the runtime library setting.
Once you've done this, make sure that both the executable and library projects have the same runtime library setting (the /MT switch you refer to), otherwise you'll get tons of strange error messages if the linker is trying to match up two different runtime libraries in the same executable.
The .lib file that is created with a "static" DLL is just an import library that handles automatic dynamic linking to all the symbols in the library. The DLL itself (that is, the .dll file) still contains all the code/symbols/etc. that you expect.
Statically linking to the .lib file just saves you from manually calling LoadLibrary()/GetProcAddress(), etc. to resolve symbols within the DLL.
You'll still need the DLL itself unless you build a true static library (that is, with all the symbols & code, rather than just the imports).

How to "add reference" in C++

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