views:

573

answers:

4

We've compiled QT 4.6 and QWT 5.2.0 for VS2005.

We're trying to derive a class from QwtDial, and the derived class has slots. So, we need to add the Q_OBJECT macro. However, when we do that, the linker chokes out this error:

error LNK2001: unresolved external symbol "public: static struct QMetaObject const QwtDial::staticMetaObject" (?staticMetaObject@QwtDial@@2UQMetaObject@@B)

I've looked at the Qwt.dll with depends, and it has that function. Looking at the .lib file with a hex editor shows it has an exact match for that name-mangled string.

We have the Qwt lib in the path. Actually, if I rename the lib, then it gives an error that it can't find the lib file. So, we know it's looking at the right lib.

If we skip the Q_OBJECT, then everything links and draws correctly using several QWT widgets, including our non-Q_OBJECT Qwt derived classes.

Does anyone know what can cause this really annoying linker issue?

UPDATE:

I've verified that the class I add the Q_OBJECT to definitely is getting a MOC file generated for it. The linker error is actually coming from this generated MOC file:

moc_GaugeWidget1.obj : error LNK2001: unresolved external symbol "public: static
    struct QMetaObject const QwtDial::staticMetaObject" 
    (?staticMetaObject@QwtDial@@2UQMetaObject@@B)

So, it's looking like something quite stange and atypical. The symbol is definitely in the lib.

+1  A: 

Hey !

I'm not sure about this answer, but here are some informations :

It seems to me that your derived class doesn't have a matching moc_ file ! The moc files are typically used when using the Q_OBJECT macro... Your project's moc informations are stored in the Makefile, Makefile.debug and Makefile.release files ! It is this file that tells which .cpp files need a moc file and which don't.

You can find documentation on the moc in QtAssistant : http://qt.nokia.com/doc/4.6/moc.html

Now, to check this, you need to go in your "generated" folder and look for a file named "moc_yourDerivedClass.cpp".

If you can't find any matching file, you need to go through the qmake process again with yourderivedClass... Maybe when you first used qmake, the Q_OBJECT macro wasn't in the class yet and therefore, no moc file has been created...

I hope it helps you a bit !

Andy M
Andy M
With that package, for example, when i add a file, i put it in the correct folder, beside my .PRO file. I launch one of the script called "generate_vcproj.bat" and the scripts generate everything... Then I use "Launch_ide.bat" and my VS launches itself with all set up (moc files as well ;) )
Andy M
As for this answer, nope... there's definitely a MOC file for this. (moc_GaugeWidget1.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const QwtDial::staticMetaObject" (?staticMetaObject@QwtDial@@2UQMetaObject@@B)) ... so, there's some other issue/bug going on.
darron
the moc_GaugeWidget1.obj is based on moc_GaugeWidget.cpp, which is the MOC file for the class I added the Q_OBJECT to.
darron
I'll look into the scripts, thanks.
darron
Hey, I've found this, maybe it could solve your problem :"The problem seemed to be the moc files which are generated by QT. There are two versions, one for debug and one for release. Switching between configurations should toggle the right files, which means one of both is always excluded from the build. If the files get mixed up, for example some moc file meant for release is included when building for debug, the file is compiled but can not be linked, since it is the wrong configuration......."
Andy M
"............You can easily check this by looking at your Generated files. Right click the files, look at the Properties and see if all files in the debug folder are excluded from the build when in release configuration and vice versa."
Andy M
+2  A: 

I am having the same problem. Well, I'm updating an old project using Qt4.4 and VC2003, and I'm using QwtPlot instead of QwtDial. The error is:

LNK2001: unresolved external symbol "public: static struct QMetaObject const QwtPlot::staticMetaObject" (?staticMetaObject@QwtPlot@@2UQMetaObject@@B)

Just that. Nothing else. I've found forum references pointing to issues with debug/release mixups and possibly something to do with removing the Qt Designer plugin.

This seems to be working for me: Add the line: "DEFINES += QWT_DLL" to the top of the project.pro file.

qmake project.pro

nmake release

Michael
A: 

The problem is with moc file.You should use Q_DECL_EXPORT (or some thing else like it) in QwtPlot definition which tell compiler this class is usable by other library but the parts of class generated in moc file dosn't contains these so when you linking these library with other program it dosn't know how to link those parts. Anyway I don't have any idea how to tell these to Qt!

bahman
A: 

Exactly the same issue here with qwt 5.2.1, qt 4.6 and VS2008. the same code compiles perfectly in Linux. All moc files are properly generated and processed, no release/debug mixed libraries are there, I am going to report it to qwt bugs when I have time.

adding QWT_DLL to the list of defines (project properties->c++->preprocessor->definitions) indeed solves the problem!