why I can't use normal C++ classes with Qt - c++

Can anyone pls tell me that, why I can't use normal C++ classes within a Qt programme. If there is any class which aren't inherited from QObject the compiler give me a linking error called,
error LNK2019: unresolved external symbol _main referenced in function _WinMain#16
I'm using Qt 4.5.2 (compiled by myself) with vs2005. Pls help me to solve this !
Edit:
Example...
//UnitManager.h
class UnitManager
{
public:
//-Some code
};
//CivilizationViewer.h
class CivilizationViewer : public QMainWindow
{
Q_OBJECT
//-some code
};
//main
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
CivilizationViewer w;
w.show();
return a.exec();
}
If I include UnitManager.h in CivilizationViewer.h compiler will give me that error. (eventhough I include UnitManager.h in main.cpp compiler will give me the error)

The error you gave doesn't have anything to do with what classes you're using. It looks like it's related to the entry point you have set for your application. Usually you want to use main() instead of WinMain() in Qt programs. Make sure your configuration is set up right.
You included a little bit of code in your question. Is that everything? If so, you're missing a main function.

Thanks for everyone. I found the error.
There is SDL.h in the UnitManager.h, so I have to add SDL.lib and SDLmain.lib (it is correct, right ?) then there is another definition for main in SDLmain.lib. So, there was a coflict between definitions of main. Therefore I added SDLmain.lib before adding qtmaind.lib. Then the problem solved by only giving a warning called,
warning LNK4098: defaultlib 'msvcrt.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
What is that warning ? I can just ignore the warning, but I like to get to know it ! Thanks

It seems like you need to link with qtmain.lib (qtmaind.lib for debug builds).
That library provides a WinMain function which is needed if you declared /subsystem:windows.
Source: http://lists.trolltech.com/qt-interest/2005-12/thread00170-0.html

It looks like you're not including the QT libraries properly... (the actual .lib file)

I think you actually made a win32 app.
try replacing your main for:
int _tmain(int argc, _TCHAR* argv[]){
your code
}
Seeing your error msg, i wouldn't guess Qt was your problem.
Did you install the Visual Studio Qt integration? Try it and make a new Qt project.

Related

C++ Compiling windows service with visual studio

hope you could help me. I got a C++ source for my service based on Microsoft example, still i get linker error compiling it:
error LNK2019: unresolved external symbol _main referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ)
as the entry point for windows services is int _tmain(int argc, TCHAR* argv[])
In my case it's void __cdecl _tmain(int argc, TCHAR* argv[]) { ... }
There are 1 header and 1 cpp files with a class used by the service and main.cpp contaning entry point and c style service related code. Subsystem is console without any custom entry point set. Still if i add classic int main(...) to the code project compiles yet the service does not start from windows service manager returning error.
Please advise how to compile this using _tmain.
Ok, still no luck with _tmain. Unfortunately i haven't tried to define WINAPI WinMain entry point.
Still if you proceed with wmain program entry point and add code mentioned by Richard Critten for a service startup SCManager performs just fine. For a complete service sample refer to MS doc.wmain will force you to use Unicode yet it shouldn't be such a problem in 2020.
Subsystem should be set as supposed to your needs and no need to set custom entry point.
Thanks to everyone commented.
UPD You have to include tchar.h in order to use _tmain, so all types of entry points will work fine.

Qt in Visual Studio 2013 with cmake - how do I get this to work?

I am currently trying integrate the library Qt in my C++ project. First I thought I could use it like any other library. I downloaded it, added the include path and libs to my VS project and tried a small sample of code that just creates a simple window with a text edit and a button. This worked and the small user interface was displayed.
Now I started to try implementing a class derived from a QWidget and realised, that it might not be that simple. The class I tried creating looked like this:
#include <QtWidgets\qstylepainter.h>
#include <QtWidgets\qwidget.h>
class MapRenderer : public QWidget{
Q_OBJECT
public:
MapRenderer(QWidget *parent = 0);
protected:
void paintEvent(QPaintEvent* event);
};
And the corresponding cpp file:
MapRenderer::MapRenderer(QWidget *parent) : QWidget(parent){
}
void MapRenderer::paintEvent(QPaintEvent *event){
QPainter p(this);
p.setPen(QPen(Qt::black, 3));
p.drawPoint(QPointF(10, 20));
}
Now as I tried compiling this I started getting linker three linker errors that looked like this:
error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __cdecl MapRenderer::metaObject(void)const " (?metaObject#MapRenderer##UEBAPEBUQMetaObject##XZ) G:\Documents\C++ Projects\HistoricalBorders\MapRenderer.obj
error LNK2001: unresolved external symbol "public: virtual void * __cdecl MapRenderer::qt_metacast(char const *)" (?qt_metacast#MapRenderer##UEAAPEAXPEBD#Z)
error LNK2001: unresolved external symbol "public: virtual int __cdecl MapRenderer::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall#MapRenderer##UEAAHW4Call#QMetaObject##HPEAPEAX#Z)
So I had a look around on the internet and found out that Qt apparently requires a far more complicated build process than a 'normal' c++ project with 'normal' libraries. I read of qmake and a Visual Studio Qt Add-In that can be used to create Qt-Projects in Visual Studio.
So I gave it a try and installed the Visual Studio Add-In and specified my Qt-version's root directory in its settings. Afterwards my project still wouldn't compile, but the only error message then was:
error LNK1112: module machine type 'x64' conflicts with target machine type 'X86'
Now I don't really get this, because my Qt library is 64bit and my project configuration also is 64bit as well as all the other libraries I am using. Furthermore, before installing the add-in I didn't have this problem. I have to say, my project is a 'normal' Visual Studio C++ console application. I saw that since I installed the VS Add-in it is also possible to choose 'Qt-console application' when creating a new project in Visual Studio. I also gave this a try but it didn't even compile after creating it. I also don't really know what the difference of a "Qt-project" to a normal VS-project is, except that the Qt libraries are included by default.
The other thing I have to mention is that I am using cmake to create my VS project file because I use version control (mercurial) and multiple people shall work on the project.
At the moment I am totally confused on how to get this library to work.
Now what is my question? Honestly, I don't really know. What I'm asking myself is:
Where does the architecture mismatch linker error come from?
Can I create a normal VS console application and get it to work with Qt?
What's the difference of a 'Qt-console application" to a normal VS project?
Is it possible to generate a Qt-compatible VS project with cmake?
EDIT: Now I uninstalled the Add-In again, reinstalled it but am now getting the old linker errors again (no longer the architecture mismatch). I have no idea why.
EDIT: Ok, some clarification. Yes, I want to use cmake. I also already have a cmakelists.txt and a findQt.cmake that I wrote myself and that asks you for your Qt root directory and then adds the necessary include paths and library paths to the project. This also works so far. E.g. the following code compiles without problems and shows an interface:
QApplication app(argc, argv);
QTextEdit *textEdit = new QTextEdit;
QPushButton *quitButton = new QPushButton("&Quit");
QObject::connect(quitButton, SIGNAL(clicked()), qApp, SLOT(quit()));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(textEdit);
layout->addWidget(quitButton);
QWidget window;
window.setLayout(layout);
window.show();
app.exec();
Now if I try to create a class as shown above (the MapRenderer) I get the linker errors also shown above. Now I thought I am doing something wrong. My only question is what. From your comment, drescherjm, I see that I problably missed the moc-step (sorry but I have no idea what exactly that is).
If you have Qt project file (.pro) (or can get it somehow), you can run
cd <pro_folder>
qmake -tp vc
to (re-)generate Visual Studio project file with Qt build process properly set up, including
moc (meta object compiler; that's what you are missing now),
uic (processing designer's files)
rcc (resource compiler).
All generated files will be compiled and linked properly.
You don't even need AddIn for that.

Must construct a QApplication before a QWidget & Invalid parameter passed to C runtime function

I finished migrating an application from Qt4 to Qt5, it compiles and everything but it crashes at a certain point. I am debugging it and trying to find why but I have reached a dead end:
Here is the stack:
main.cpp line 373:
TouchSwibz w(NULL, NULL, renderMode ? renderMode : AppSettings::RASTERMODE);
When it reaches the breakpoint and I try to go further, it crashes with the usual
"This application has requested the Runtime to terminate it in an
unusual way."
And the aplication output shows
QWidget: Must construct a QApplication before a QWidget
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
I have thought maybe its because the widget is being initialized when the main window is being created, but what can be done to solve this? What would be a good workaround? I dont even know if this is the real issue.
I work under Windows 7 x64 using Qt 5.2.1 and compiling with mingw 4.8 32bit, the application is in 32bits also. Everything is compiled with the same kit.
I dont know what other useful information I can provide. I tried stepping inside the QwtSlider constructor but I cant.
I managed to solve it by compiling all the libraries in debug mode, turns out having libraries in release mode while building your application in debug mode will make undefined behaviour happen.
You're most likely having non-local instances of QWidget type. By definition, those will be initialized before main starts executing, so before QApplication gets constructed. The code below reproduces the problem:
#include <QLabel>
#include <QApplication>
QLabel label("Hello, world!");
int main(int argc, char ** argv)
{
QApplication app(argc, argv);
label.show();
return app.exec();
}
The fix is to delay the construction until there is a QApplication object:
#include <QLabel>
#include <QApplication>
// Won't ever be a dangling pointer.
QPointer<QLabel> label;
int main(int argc, char ** argv)
{
QApplication app(argc, argv);
QLabel label_("Hello, world!");
label.reset(&label_);
label->show();
return app.exec();
}
I just solved a similar problem, and here is my detailed situation and solution:
I use VS with Qt add-on;
and Qt version is 5.7 64 bit (but this is not important)
I compiled successfully in both debug and release mode;
I could run it in debug mode but not in release, where caused an massage "Must construct a QApplication before a QWidget".
[IMPORTANT] I first compiled and tested it under DEBUG mode, and then I met some computational thresh-hold that encouraged me to use RELEASE mode.
[IMPORTANT] I used some third-party library, related to Qt GUI component, that requires you to add an external dependency to the project.
[IMPORTANT] I just copy the configures in the Project Property page from DEBUG to RELEASE, like exteral C++ library or External Dependencies.
I finally found the reason. In the project's Property Pages dialog box -> Linker folder -> Input property page -> Additional Dependencies, one of the external library should be replaced as a release version one, which have different name, in my case, QGLViewerd2.lib to QGLViewer2.lib.

linking vs 2012 c++ GDAL

I created a standard windows application with VS 2012 Pro. Just a main.cpp that looks like this:
#include "gdal_priv.h"
#include "cpl_conv.h"
int main(int argc, char* argv[])
{
GDALAllRegister();
return 0;
}
I have set my include path properly. I have gdal_i.lib in my Linker -> Input -> Additional Dependencies.
Link fails with the following message:
1>main.obj : error LNK2019: unresolved external symbol
_GDALAllRegister#0 referenced in function _main
(A scad of other symbols are missing as well, but this one should be easy.)
I used dumpbin and GDALAllRegister appears in the exported symbols. It does appear as "GDALAllRegister", not as "_GDALAllRegister#0".
I tried downloading and using the dev build, and also built myself. Same results.
I just know this is something simple, but I'm totally brain-cramping here. What have I done wrong?
Thanks.
-reilly.
I said it was simple and stupid, and it was.
I had the build manager set to build 32 bit.
Another 4 hours of my life I'll never get back.
Thanks to Manuell for his suggestion. It got me looking in a different direction and I found it.
Sorry, community. This is what comes from programming tired.
-reilly.
This kind of error is typical of a "Calling Convention" mismatch between EXE and LIB.
Check you have __cdecl (/Gd) in "Configuration Properties" -> C++ -> Advanced -> "Calling Convention"

error LNK2019: unresolved external symbol _WinMain#16 referenced in function ___tmainCRTStartup

While I am running the simple code as below I have two errors as following:
#include <iostream>
#include <string>
using namespace::std;
template <class Type>
class Stack
{
public:
Stack (int max):stack(new Type[max]), top(-1), maxsize(max){}
~Stack (void) {delete []stack;}
void Push (Type &val);
void Pop (void) {if (top>=0) --top;}
Type& Top (void) {return stack[top];}
//friend ostream& operator<< (ostream&, Stack&);
private:
Type *stack;
int top;
const int maxSize;
};
template <class Type>
void Stack <Type>:: Push (Type &val)
{
if (top+1<maxsize)
stack [++top]=val;
}
Errors:
MSVCRTD.lib(crtexew.obj) : error LNK2019: unresolved external symbol _WinMain#16 referenced in function ___tmainCRTStartup
What Should I do?
Thats a linker problem.
Try to change Properties -> Linker -> System -> SubSystem (in Visual Studio).
from Windows (/SUBSYSTEM:WINDOWS) to Console (/SUBSYSTEM:CONSOLE)
This one helped me
As the others mentioned you can change the SubSystem to Console and the error will go away.
Or if you want to keep the Windows subsystem you can just hint at what your entry point is, because you haven't defined ___tmainCRTStartup. You can do this by adding the following to Properties -> Linker -> Command line:
/ENTRY:"mainCRTStartup"
This way you get rid of the console window.
If you are having this problem and are using Qt - you need to link qtmain.lib or qtmaind.lib
Besides changing it to Console (/SUBSYSTEM:CONSOLE) as others have said, you may need to change the entry point in Properties -> Linker -> Advanced -> Entry Point. Set it to mainCRTStartup.
It seems that Visual Studio might be searching for the WinMain function instead of main, if you don't specify otherwise.
Include <tchar.h> which has the line:
#define _tWinMain wWinMain
If you use Unicode Character Set, but the entry wasn't set, you can specify /ENTRY:"wWinMainCRTStartup"
If you actually want to use _tWinMain() instead of main()
make sure your project relevant configuration have
Linker-> System -> SubSystem => Windows(/SUBSYSTEM:WINDOWS)
C/C++ -> Preprocessor -> Preprocessor Definitions => Replace _CONSOLE with _WINDOWS
In the c/cpp file where _tWinMain() is defined, add:
#include <Windows.h>
#include <tchar.h>
i don't see the main function.
please make sure that it has main function.
example :
int main(int argc, TCHAR *argv[]){
}
hope that it works well. :)
If your project is Dll, then the case might be that linker wants to build a console program. Open the project properties. Select the General settings. Select configuration type Dynamic Library there(.dll).
I'm not sure where to post this answer of mine but I think it's the right place.
I came across this very error today and switching the subsystems didn't change a thing.
Changing the 64bit lib files to 32bit (x86) did the trick for me, I hope it will help someone out there !
Your tried to turn that source file into an executable, which obviously isn't possible, because the mandatory entry point, the main function, isn't defined. Add a file main.cpp and define a main function. If you're working on the commandline (which I doubt), you can add /c to only compile and not link. This will produce an object file only, which needs to be linked into either a static or shared lib or an application (in which case you'll need an oject file with main defined).
_WinMain is Microsoft's name for main when linking.
Also: you're not running the code yet, you are compiling (and linking) it. C++ is not an interpreted language.
If you are using CMake, you can also get this error when you set SET(GUI_TYPE WIN32) on a console application.
The erudite suggestions mentioned above will solve the problem in 99.99% of the cases. It was my luck that they did not. In my case it turned out I was including a header file from a different Windows project. Sure enough, at the very bottom of that file I found the directive:
#pragma comment(linker, "/subsystem:Windows")
Needless to say, removing this line solved my problem.