Configuring Qt Creator with executable and DLL project - c++

I am new to QT Creator coming from Visual Studio. I have a session with two projects in it. One is a DLL with some classes that I intend to use for other purposes. The other is an executable console app that uses some of the classes from the DLL.
I currently have these two projects side by side in QT Creator. I can include the header files from the DLL in my EXE project using relative paths "../MyPrject/header.h". But how do I get QT Creator to link and then copy the DLL into the executable debug folder for debugging.
Am I doing this all wrong? Is there a better way? If it includes adding code to the .pro file, please include a link so that I can learn more.

You should make some dependencies between this projects.
opening both projects - you have done.
on editor view, right click on exe-project and select add library...
follow creator hints to add it.
2nd option: you can make subprojects. follow QtCreator: Creating Projects from documentation (help view in Qt Creator)

GwyenBleidD provided a good starting point for including DLLs.
I however, have made a habit out of modifying the .pro file directly here and honestly I prefer to modify the .pro file in the event that something goes haywire.
Suppose I wanted to use the winsock DLL.
In the .pro file, I'd first specify the .dll's corresponding .lib file:
# WinSock2 library (ws2_32.lib file)
LIBS += -lws2_32
# Path to the WinSock2 library
LIBS += -L"c:/mylibraries/"
Additionally, you'll need to specify the include path to the header files here:
INCLUDEPATH += "c:/Program Files (x86)/Microsoft Visual Studio 10.0/VC/INCLUDE"
Thirdly, in my code I'd have to make sure to include the headers for it:
// I ASSUME it'll be found under something like the
// Visual Studio/VC/INCLUDE directory mentioned above.
#include <winsock2.h>
Lastly, you need to ensure that your application can find the .dll file, typically pointed to using the %PATH% environment variable.
With regards to your setup, I'd make sure that your sub-projects are configured so that the library compiles FIRST (obviously). And then ensure that the LIBS variable in your .Pro project points correctly to your .lib destination according to the build configuration (debug|release).
Qt's PRO (qmake) isn't as terrible as some make it out to be. Just give it a solid half-hour to an hour and you'll get the hang of it. I assume though that you have a solid understanding of libs and DLLs and what not.
http://qt-project.org/doc/qt-5.0/qtdoc/qmake-manual.html

The right way is to switch on CMake based project and keep exe and dll within one root project. The main benefit of this decision is IDE independent approach: you can use Qt Creator, CLion, Visual Studio without any changes in project definition. As the start point consider to see the example project https://github.com/anatoly-spb/cmake_exe_dll

Related

Qt-Based C++ Project Works If Run From cmd.exe But Not From Within Qt Creator

I am writing a very minimal C/C++ Qt-based application for Windows (only Windows -- not cross platform at all) that uses a VISA library (visa64.dll) to talk to some external hardware. That library, in turn, uses some other libraries:
(screenshot from Dependency Walker a.k.a. depends.exe)
Originally I wrote it in Visual Studio and it worked great. Then I ported it to Qt Creator (using Qt5, w/ MSVC 2015 Visual C++ toolchain) and I got runtime errors. It knows where to find the external header files, so I think my INCLUDEPATH is right, and it builds fine so I think the LIBS variables in my .pro file are right, which is to say it can find the .lib files it needs. However, the first API I call from this external library (viOpenDefaultRM) returns the following error: VI_ERROR_LIBRARY_NFOUND. This happens whether I make a debug build or a release build, and whether or not I am running it with a debugger. As long as I run the program from within Qt Creator, it gets runtime errors.
Here is my .pro file:
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += main.cpp
INCLUDEPATH += $$PWD/'../../../../Program Files/IVI Foundation/VISA/Win64/Include'
LIBS += -L$$PWD/'../../../../Program Files/IVI Foundation/VISA/Win64/Lib_x64/msc/' -lvisa64
INCLUDEPATH += $$PWD/'../../../../Program Files/IVI Foundation/VISA/Win64/Include'
DEPENDPATH += $$PWD/'../../../../Program Files/IVI Foundation/VISA/Win64/Include'
The paths that end with /Include have header (.h) files (it's a C library), and the path that ends with /msc has a .lib file. The .lib files are not static libraries, they are the interface files for some corresponding DLLs. Those DLL files are in C:\System32. There are also 32-bit versions in C:\SysWOW64. They may also exist elsewhere but if they do I am not aware of it.
Now, if I run it from cmd.exe it works fine. That is, if I open a cmd.exe terminal window and navigate to my Qt project's build directory (c:\blah\blah\blah\obj\debug\) and run the executable from cmd.exe, I get no runtime errors. It can connect to the external hardware, talk to it, all good things are happening, much rejoicing.
I've done a decent amount of searching and researching about this problem, and I am somewhat cursed by the fact that most people have the opposite problem, which means that problem (the opposite one of mine) is what turns up in Google/DuckDuckGo/StackOverflow/forum.qt.io/doc.qt.io searches. That problem usually has to do with missing/misplaced Qt libraries. Here is an example. The answer to this question usually ends up with a link to a page on how to deploy Qt projects for Windows, e.g. this article.
Also I've read this article from Qt on how to add libraries to your project, and it didn't help me out, but I could be missing something and/or doing it wrong.
This might be something really dumb I'm missing and frankly I hope it is. Thanks*10^6.
TL;DR: The kit I was using to compile in Qt Creator had a different PATH set than my system PATH. To fix this, I did echo %PATH in cmd.exe and copied all the stuff that had to do with the drivers I'm trying to use into the PATH for the kit I'm using in Qt Creator. More details below.
I got this to work this morning. As suggested by #adrien-lerevat, when run from within Qt Creator, my executable couldn't find some DLLs it needed. The long and short of it is that I was defining a PATH in my kit (a "kit" in Qt is basically a compiler, a debugger, and some environment variables) that was different from, and not a superset of, my normal system path. I had inherited this kit for other purposes, you see, from other projects, and I didn't realize a PATH could be set in it, or that I was setting one. So to find the PATH I was setting for Qt Creator, I went to the Tools dropdown and selected Options..., then Build & Run, then Kits. Then click on the kit you are using to edit it. As such:
That should give you a list of stuff, one thing of which is called Environment. That should have a Change... button you can press:
which should open a new window with all your environment stuff:
(screenshot is from after I fixed the problem)
This is where I found PATH, as well as some library and include paths that were worth knowing about. So now that I knew what my Qt Creator PATH was, I opened cmd.exe and typed the command echo %PATH% to find out what my system PATH was. I grabbed everything that had to do with these VISA drivers I'm using (basically anything with VISA and/or IVI Foundation in the path) and pasted them into my PATH in Qt Creator. This was the list of stuff I pasted in there to make it work:
C:\WINDOWS\system32;C:\Program Files\IVI Foundation\VISA\Win64\ktvisa;C:\Program Files\IVI Foundation\VISA\Win64\bin;C:\Program Files (x86)\IVI Foundation\VISA\WinNT\bin;C:\Program Files (x86)\IVI Foundation\VISA\WinNT\Bin\;C:\Program Files\IVI Foundation\VISA\Win64\Bin\;C:\Program Files (x86)\IVI Foundation\VISA\winnt\agvisa;C:\Program Files\Keysight\IO Libraries Suite\bin;C:\Program Files (x86)\Keysight\IO Libraries Suite\bin;C:\Program Files (x86)\IVI Foundation\VISA\WinNT\ktvisa;C:\Program Files (x86)\IVI Foundation\IVI\bin;C:\Program Files\IVI Foundation\IVI\bin;
I added c:\system32 because I know that's where visa64.dll is, which is at least one top-level DLL I know I need. Oddly enough, though, when I added just c:\system32 without all the VISA and IVI Foundation stuff, that didn't work. So, I don't know if everything I added to my Qt Creator path was necessary, as I've just come upon this solution, but once I pare down the list to find out what all I actually needed I will add that information here. Just in case anyone else ever comes across this problem or is curious. And for the sake of completeness I suppose. Okay thanks everyone ;)

How to create library that uses some other libraries?

I'm trying to create a graphic library (nothing serious, just to learn stuff). In Visual Studio I have one solution and two projects in it - dll and exe. For window management I use GLFW library. In my own window class I want to have a private memeber of GLFW Window structure. The problem is that my exe project doesn't know what GLFW is - it doesn't know where to find #include <glfw/glfw3>.
My question is - what's the proper way to create such library that uses other libraries? Setting the exe project to include all those libraries doesn't sound like a good idea to me.
Since you are using visual studio, then Microsofts documentation is a great place to get information. https://learn.microsoft.com/en-us/cpp/build/dlls-in-visual-cpp?view=vs-2019 they have a description on DLL’s and how to create them and also how to link DLL’s to projects.
Thanks to #Manuel I figured out how to do it: both - dll and exe projects, have to include libraries' header files.
My solution: in dll I use precompiled headers so all libraries' header files are included in that file with a relative path. In dll project settings I put proper paths so any libraries files will know how to find their headers. What's important is that my exe project includes one header file from my dll and that file include precompiled header so exe project 'knows' everything it needs about libraries.
Thanks again #Manuel for your help!

how to link Qt with a visual studio c++ application project?

I have Qt 5.12.0 in a folder.
I need to create a dll and/or a bin project that can connect with a QML program.
My problem is that the vs project can't find the Qt files I need.
#include <QGuiApplication>
does not work.
This topic is the continuity of this one
How to link libraries to a project on visual studio? where I shared my problems with linking my dll with my bin project and to link Qt.
So I use a batch file to set the environment variable before launching visual studio. I use these variables to get the path to the Qt include folder, Qt lib etc.
Here is what I tried.
include the directory that contains the headers I need (I guess) :
configuration properties -> C/C++ -> General -> other include directories ->$(QT_INC)/. QT_INC is the path to the include folder. I also tried to write $(QT_INC)/* and $(QT_INC)/QtGui/. In any case,
#include <QGuiApplication>
couldn't compile.
i also added the path to the library folder :
linker->General->Additional library directories->$(QT_LIB)/
and some lib files in :
linker->entry->additionnal dependencies->Qt5Quick.lib;Qt5Gui;lib;Qt5Core.lib
none of these steps creates any error. It just doesn't help to find QGuiApplication.h nor QObject or anything I need.
I know my paths are correct and that using the environment variable like this works as I linked my dll using this method, and because wrong paths generates errors.
How to add Qt to my solution or to a project ?
thanks in advance
It works. The path was incorrect. There were "/" instead of "\" I think. And a synthax error in the batch file.
It's possible to add the header files of Qt by including the path in the properties.
include just the directory include of the Qt folder. Then, include headers again and again until all the errors are gone.
only for QGuiApplication, I need to include this
#include <QtGui/qtguiglobal.h>
#include <QtGui/qcoreapplication.h>
etc. all the includes of the beggining of QGuiApplication.h actually
here is the link to my other post I made about linking Qt to visual studio. How to link libraries to a project on visual studio? The problem was about the path to the dll.

Qt Release DLL Error

I have a project in Qt Creator and am trying to compile a static release. To do so, I have added "static" to my "CONFIG" option in my .pro file.
After rebuilding all the files, I get a folder named "release" with an executable and a few other files inside of it. When trying to execute the generated file, I get an error that reads as such:
"The procedure entry point __cxa_throw_bad_array_new_length could not be located in the dynamic link library C:\Qt\5.5\mingw492_32\bin\QtCore.dll"
This error message remains whether I use mingw 5.5.0 or 5.4.2 to compile the files.
Using dependency walker and coping the "correct" QT dll files also does not resolve the problem.
What I know already: This error happens to people who copy the wrong QTCore.dll to their project folder. However, since I am not copying any .dll files, I don't know how to use this information to my advantage.
In conclusion, my question is: How do I stop this error from occurring? Moreover, is there a better way to statically compile a qt application?
To build static release of your application you basically need two things:
1) add
CONFIG += static
in your .pro file (you did it) and don't copy any Qt dlls.
2) you need to build static Qt
https://wiki.qt.io/Building_a_static_Qt_for_Windows_using_MinGW
By default Qt is installed prepared for dynamic linking, this is why you need to build static Qt on your own.
You may want to look also at this great Q&A:
Qt static linking and deployment
but it deals mainly with Qt4. Idea is the same.
After you will build static Qt you will need to rebuild your application. And don't copy any Qt dlls.

Adding my DLL into a Visual Studio project in C++

I am working on a project that involves making a dynamic link library, so I want to test it in a console app in Visual Studio.
The DLL is also made in Visual Studio, it doesn't have much, just a few functions in it. I'm not sure if I'm just supposed to include the librarys header in the include directories panel in Properties, or do something else
A lot of people say I'm supposed to add its corresponding .lib file in the Library or Reference directory, but I'm not sure that VS generates a .lib file alongside the DLL. I'm using VS 2015.
I don't have VS in front of me this very moment, but these should be the general steps to set it up:
Properties->Linker->Input: your.lib
Properties->Linker->Additional Library Directories: ../your/bin
Properties->General->Compiler->Additional Include Directories: ../your/include
To build your app, the DLL's API headers must be in the include for the compile-time, it's LIB files in the bin for the link-time. Once you have your app EXE, all you need is the DLL to be in the same folder as your EXE when it executes.
You might also want to add the dll project and the app project into a common solution in VS and add (right click) Project Dependency from the app to the dll. This ensures correct order of building, assuming you are going to build the dll at all.
You can also do what I did.
You can create a Libs directory inside of your Solution directory.
You can then place your .DLL files inside of the Libs directory or some sub-directory inside of Libs
In my case, I added the entire SFML-2.3.2 directory in there, which included the source-code, .lib files, and .dll files.
I did link up what I could in the project properties, but I used Visual Studio's macros to fill in the path name to the Solution directory. Just in case I wanted to put this in version control and work on it from multiple machines.
Then I opened up the Project's Property Page.
Within the property page, I went to Build Events -> Post-Build Event -> Command Line
Within the Command Line, you can add a copy command that will copy any needed files into the same directory as the executable that will need them.
In my case I used: copy "$(SolutionDir)Libs\SFML-2.3.2\bin\*" "$(TargetDir)"
I could have written multiple commands to copy just the individual files that I needed, but I had spent a good three hours trying to get SFML to work without actually installing it.