8

I tried to write a simple Qt application like this:

main.cpp:

#include <QApplication>

class MyApp : public QApplication {
        Q_OBJECT
public:
        MyApp(int argc, char* argv[]);
};

MyApp::MyApp(int argc, char* argv[]) :
        QApplication(argc,argv) {
}

int main(int argc, char* argv[]) {
    MyApp app(argc,argv);
    return app.exec();
}

But when I tried to compile and link it with Qt Creator 2.3.1 (Qt 4.7.4) I get 3 "unresolved external symbol" errors:

  • main.obj:-1: error: LNK2001: unresolved external symbol
    ""public: virtual struct QMetaObject const * __thiscall MyApp::metaObject(void)const "
    (?metaObject@MyApp@@UBEPBUQMetaObject@@XZ)".

  • main.obj:-1: error: LNK2001: unresolved external symbol
    ""public: virtual void * __thiscall MyApp::qt_metacast(char const*)"
    (?qt_metacast@MyApp@@UAEPAXPBD@Z)".

  • main.obj:-1: error: LNK2001: unresolved external symbol
    ""public: virtual int __thiscall MyApp::qt_metacall(enum QMetaObject::Call,int,void * *)"
    (?qt_metacall@MyApp@@UAEHW4Call@QMetaObject@@HPAPAX@Z)".

I think they are somehow related to the MetaObjectCompiler of Qt, but I can't figure out a solution. I know it's not considered good programming style in c++ to put declarations and definitions in one file, but that's not the point here. In my opinion it should be possible since there is nothing syntactically wrong here.

stijn
  • 34,664
  • 13
  • 111
  • 163
Karsten
  • 1,814
  • 2
  • 17
  • 32

4 Answers4

13

Use the code below, and make sure to run qmake (Build > Run qmake) before building.

#include <QApplication>

class MyApp : public QApplication {
  Q_OBJECT
public:
  MyApp(int argc, char* argv[]);
};

MyApp::MyApp(int argc, char* argv[]) :
  QApplication(argc,argv) {
}

int main(int argc, char* argv[]) {
  MyApp app(argc,argv);
  return app.exec();
}

#include "main.moc"

Explanation: When you include the Q_OBJECT macro, this signals Qt to do a bunch of stuff that is not standard C++, such as signals and slots. It does this by running moc, which in large part is a code generator. Running qmake creates the metadata so that when your project is built, it knows which files to moc, etc.

Dave Mateer
  • 17,608
  • 15
  • 96
  • 149
  • 1
    This worked fine. But I still don't know why it works without including the .moc file when I put the declaration part into a seperate header file. – Karsten Nov 23 '11 at 19:26
  • 2
    You rarely need to explicitly include any `.moc` files. Qt handles this for you. In fact, the *only* time I have ever used it is when creating sample programs like the one above where you only have a `main.cpp`. I think the reason is that `qmake` automatically handles scanning header files for you, but not cpp files, because those don't normally contain stuff that needs `moc`-ed. http://doc.qt.nokia.com/latest/moc.html – Dave Mateer Nov 23 '11 at 19:30
3

I think you need to moc the file and include the resulting main.moc at the bottom.

Ahmish
  • 1,151
  • 8
  • 8
0

I think this has something to do with QMake. It's not that the executable app can't see the exported DLL class. It's that the obj file for the class doesn't exist. Running QMake from the QT Creator Build menu and then building seems to work.

Why does this Simple Qt Application not link

Community
  • 1
  • 1
narmaps
  • 373
  • 5
  • 16
0

I've just met the same problem, and it has been solved by changing the Character set of my header from Unicode to ANSI.

Emilia
  • 1