[Qt-interest] Q_OBJECT in DLL - Release build warnings

Oliver.Knoll at comit.ch Oliver.Knoll at comit.ch
Wed Feb 10 13:18:30 CET 2010


Catalin Roman wrote on Wednesday, February 10, 2010 11:22 AM:

> ...
> :( ... my intention was just to figure out if it's just a project
> layout problem (since both samples performed basically the same
> thing:calling a function from a DLL) or something deeper.

Your problem is that you add the HEADER counterfoo.h to the CounterBar project! Why do you do that? Your intention is probably to specify a DEPENDENCY on that header, but that is NOT done with HEADERS += whatever.h!

Check out http://doc.trolltech.com/4.6/qmake-variable-reference.html#dependpath for how the setup dependencies (so that when the headers in the CounterBar project change also dependend projects are re-build as needed).

Anyway, once you remove the HEADERS += ../CounterFoo/counterfoo.h from your CounterBar.pro your example compiles fine without warnings (once I manually copy the generated DLL into the 'lib' subfolder, before compiling CounterBar).

And it is very obvious why you received those warnings: by adding the header counterfoo.h AGAIN to your CounterBar project, it gets mock'ed ONCE AGAIN (because qmake realises that this header/class is derived from QObject, contains the Q_OBJECT macro etc.). And then the resulting moc_counterfoo.cpp gets compiled ONCE again into your *.exe, and the same code is now once in your DLL and once in your *.exe! And off course the second time the __declspec(dllimport) totally does not make sense for the compiler, hence the warnings ;)

See the output WITH the HEADERS += specified:

Z:\resources\work\Qt\CounterFooBar\CounterBar>mingw32-make
...
g++ -c -g -frtti -fexceptions -mthreads -Wall -DUNICODE -DQT_LARGEFILE_SUPPORT -
DQT_DLL -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"c:\Qt\2009.05\qt\include\QtCore" -I
"c:\Qt\2009.05\qt\include" -I"c:\Qt\2009.05\qt\include\ActiveQt" -I"debug" -I"c:
\Qt\2009.05\qt\mkspecs\win32-g++" -o debug\main.o main.cpp

The main.cpp gets compiled, that's fine. Here the compilation should actually stop, and the link stage should begin, but instead...

C:/Qt/2009.05/qt/bin\moc.exe -DUNICODE -... ..\CounterFoo\counterfoo.h -o debug\moc_counterfoo.cpp

... the counterfoo.h header is moc'ed ONCE AGAIN and ...

g++ -... debug\moc_counterfoo.cpp

... compiled, resulting in those warnings:

debug\moc_counterfoo.cpp:40: warning: 'CounterFoo::staticMetaObject' redeclared
without dllimport attribute after being referenced with dll linkage


It means exactly what it sais: you have re-declared the method CounterFoo::staticMetaObject (in the 2nd generated moc_counterfoo.cpp), after you had already #included (from your main.cpp) the same method from the 1st counterfoo.h header, where you (correctly) specified the dll linkage stuff (your CounterBar project sees __declspec(dllimport)). And __declspec(dllimport) is indeed different than "no DLL linkage specification", as in the 2nd case.


Lesson learned: always read the output of your compiler/linker and take extra-care what gets mocked/compiled/linked ;) And take warnings seriously, it pais off (as you did ;)

Cheers, Oliver
-- 
Oliver Knoll
Dipl. Informatik-Ing. ETH
COMIT AG - ++41 79 520 95 22



More information about the Qt-interest-old mailing list