Thread: staticMetaObject

来源:互联网 发布:大数据考研科目 编辑:程序博客网 时间:2024/04/29 05:31
  1. #1
    Tiber 
    Tiber is offlineBeginner
    Join Date
    Apr 2008
    Posts
    5
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default staticMetaObject

    I'm sort of new to Qt, but I've run this by some more experienced coworkers, and they're stumped as well.

    My job is to port the application from Qt3 to Qt4.3. I am using VS2005 with vs integration.

    Pretty much all of the code is divided into dll projects. I've got one of the projects pretty much done except for a linker error.

    Here's what it is:

    Qt Code:
    Switch view
    1. class MyClass : public BaseClass
    2. {
    3. Q_OBJECT
    4. public:
    5. ...
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    Switch view
    1. class DLL_EXPORT_MACRO BaseClass : public QObject
    2. {
    3. Q_OBJECT
    4. public:
    5. ...
    To copy to clipboard, switch view to plain text mode 
    Then I get this:

    Qt Code:
    Switch view
    1. moc_myclass.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const BaseClass::staticMetaObject" (?staticMetaObject@BaseClass@@2UQMetaObject@@B)
    To copy to clipboard, switch view to plain text mode 

    Note that the base class and child class are in different projects in different directories, though the child project obviously includes the folder the base class's header is in.

    In my search, I haven't seen anyone else with quite this situation, but there are people who have had a similar problem because they didn't qmake properly. Because of this, I'm wondering if I need to mess with the project settings to link in the base class's moc file, though I'm not sure how to go about this.

    Any questions/suggestions would be greatly appreciated.
    Reply With QuoteReply With Quote
  2. #2
    wysota's Avatar
    wysota 
    wysota is offlineThe "Q"          
    Nokia Certified Qt Developer
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    32,982
    Thanks
    3
    Thanked 4,928 Times in 4,726 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Blog Entries
    4
    Wiki edits
    10

    Default Re: staticMetaObject

    Is the file created by moc updated when you change contents of your class? In other words - are you mocing the class?
    Reply With QuoteReply With Quote
  3. #3
    Tiber 
    Tiber is offlineBeginner
    Join Date
    Apr 2008
    Posts
    5
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: staticMetaObject

    The vs integration automatically re-mocs when you rebuild unless you manually disable it I believe. The parent class is up to date and builds properly, including the moc. The child class compiles, but the child's moc gives the linker error.

    I forgot to mention, I've also tried making the child project dependent on the parent project.
    Reply With QuoteReply With Quote
  4. #4
    wysota's Avatar
    wysota 
    wysota is offlineThe "Q"          
    Nokia Certified Qt Developer
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    32,982
    Thanks
    3
    Thanked 4,928 Times in 4,726 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Blog Entries
    4
    Wiki edits
    10

    Default Re: staticMetaObject

    What does DLL_EXPORT_MACRO contain? Why don't you use the one Qt provides for you?
    Reply With QuoteReply With Quote
  5. #5
    Tiber 
    Tiber is offlineBeginner
    Join Date
    Apr 2008
    Posts
    5
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: staticMetaObject

    It's a #define for __declspec(dllexport).

    As for why, I asked a coworker, and he said he saw no advantage to using one way over the other, since the Qt way is probably internally the same or very similar(at least for windows).
    Reply With QuoteReply With Quote
  6. #6
    wysota's Avatar
    wysota 
    wysota is offlineThe "Q"          
    Nokia Certified Qt Developer
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    32,982
    Thanks
    3
    Thanked 4,928 Times in 4,726 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Blog Entries
    4
    Wiki edits
    10

    Default Re: staticMetaObject

    Quote Originally Posted by Tiber View Post
    It's a #define for __declspec(dllexport).
    In that case that's probably wrong.

    As for why, I asked a coworker, and he said he saw no advantage to using one way over the other, since the Qt way is probably internally the same or very similar(at least for windows).
    Similar and the same are much different  The point is that it should be dllexport when building a library and dllimport when using it. Are you building or using? If the latter then probably the library didn't export the symbols needed.
    Reply With QuoteReply With Quote
  7. #7
    Tiber 
    Tiber is offlineBeginner
    Join Date
    Apr 2008
    Posts
    5
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: staticMetaObject

    My coworker wants to confirm this with Qt Support, but it looks like he found a solution.

    For anyone else who has this problem, I'll explain as best I can his answer.

    Between Qt 3 and Qt 4, the Q_OBJECT macro underwent some changes. In Qt 3, the macro made a static struct in a private section, then made accessor and modifier functions.
    In Qt 4, there's now a static const struct in the public section. Don't ask me how exactly that creates errors, but here's the short version:

    In Qt 3, it was perfectly valid to have a class with the Q_OBJECT macro, and then have a child class that also has Q_OBJECT. In Qt 4, it is not. So just remove Q_OBJECT from the child class and it will still work.
    Reply With QuoteReply With Quote
  8. #8
    wysota's Avatar
    wysota 
    wysota is offlineThe "Q"          
    Nokia Certified Qt Developer
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    32,982
    Thanks
    3
    Thanked 4,928 Times in 4,726 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Blog Entries
    4
    Wiki edits
    10

    Default Re: staticMetaObject

    Quote Originally Posted by Tiber View Post
    In Qt 3, it was perfectly valid to have a class with the Q_OBJECT macro, and then have a child class that also has Q_OBJECT. In Qt 4, it is not. So just remove Q_OBJECT from the child class and it will still work.
    Huh? That's not true. QWidget has Q_OBJECT declared. If what you are saying was true, you couldn't have any subclass of QWidget that implements new signals, slots or properties. And that's obviously not the case. I still say you have a problem with moc and linker.
    Reply With QuoteReply With Quote
  9. #9
    Tiber 
    Tiber is offlineBeginner
    Join Date
    Apr 2008
    Posts
    5
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: staticMetaObject

    Actually you're right. It compiles (which I thought it wouldn't do without Q_OBJECT), but I haven't tested it. I got a little overeager when my coworker said he found a solution, and didn't stop to think about it. Chalk it up to absentmindedness.

    Anyway, looking at it more, you had the right idea. The problem was that some preprocessor definitions that were needed (including the one necessary for __declspec(dllimport)) weren't in the project file. Somehow everything managed to work for everyone else still using the Qt 3 build, but not for me working on the Qt 4 port. Just another unexplained mystery of the universe.

    Anyway, thanks for your help.
    Reply With QuoteReply With Quote
  10. #10
    berw 
    berw is offlineBeginner
    Join Date
    Jan 2011
    Posts
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: staticMetaObject

    Hi,
    I had a similar problem with deriving my own classes from QtAbstractPropertyManager and QtAbstractEditorFactory for the customization of Qtpropertybrowser.

    Error messages while linking in VS2008 were:

    1>moc_QtImgCoordPropertyManager.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const QtAbstractPropertyManager::staticMetaObject" (?staticMetaObject@QtAbstractPropertyManager@@2UQM etaObject@@B)
    1>moc_QtPointImgEditFactory.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const QtAbstractEditorFactoryBase::staticMetaObject" (?staticMetaObject@QtAbstractEditorFactoryBase@@2U QMetaObject@@B)

    including "#define QT_QTPROPERTYBROWSER_IMPORT" in the header files of the derived classes resolved the problem (the effect is that it changes the QT_QTPROPERTYBROWSER_EXPORT define in file qtpropertybrowser\src\qtpropertybrowser.h

    Hope this info can be helpful for somebody.
    Reply With QuoteReply With Quote
  11. #11
    dresha48 
    dresha48 is offlineBeginner
    Join Date
    Jan 2010
    Posts
    13
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: staticMetaObject

    I just found what is this problem about and how to solve it. I`m changing big project from QT3 to QT4 - and last mistakes was :
    "error LNK2001: unresolved external symbol "public: static struct QMetaObject const <CLASS_NAME>::staticMetaObject" (?staticMetaObject@<CLASS_NAME>@@2UQMetaObject@@B) "

    The most closest to solution was 'Tiber' here :"The problem was that some preprocessor definitions that were needed (including the one necessary for __declspec(dllimport)) weren't in the project file. Somehow everything managed to work for everyone else still using the Qt 3 build, but not for me working on the Qt 4 port. Just another unexplained mystery of the universe."
    and 'nobledeveloper' from other forum: http://www.qtforum.org/article/17697...externals.html

    At first I wasn't so sure that they are correct and I was trying to find the reason from other ways. I created tested solution with 2 dll`s . With such classes:
    parent ( C/C++ -> Preprocessor Difinitions: ...TESTLIB_LIB; ):

    #ifdef TESTLIB_LIB
    # define TESTLIB_EXPORT Q_DECL_EXPORT
    #else
    # define TESTLIB_EXPORT Q_DECL_IMPORT
    #endif
    class TESTLIB_EXPORT testLib: public QObject
    {
    Q_OBJECT
    ....
    }

    child ( C/C++ -> Preprocessor Difinitions: ...TEST2LIBCHILD_LIB; ):

    #ifdef TEST2LIBCHILD_LIB
    # define TEST2LIBCHILD_EXPORT Q_DECL_EXPORT
    #else
    # define TEST2LIBCHILD_EXPORT Q_DECL_IMPORT
    #endif

    class TEST2LIBCHILD_EXPORT test2LibChild:
    public testLib
    {
    Q_OBJECT
    ...
    }


    and I get no errors...
    But if I add to child "C/C++ -> Preprocessor Difinitions: TESTLIB_LIB" I will get such a link error "error LNK2001: unresolved external symbol "public: static struct QMetaObject const testLib::staticMetaObject" (?staticMetaObject@testLib@@2UQMetaObject@@B)"

    To solve my problem I added for each sub-project dlldefslocal.h with corresponding defines , for example:

    #ifdef DVL_HIO_DIALOGIO_PLUGIN
    # define DVL_HIO_DIALOGIO_PLUGIN_EXPORT Q_DECL_EXPORT
    #else
    # define DVL_HIO_DIALOGIO_PLUGIN_EXPORT Q_DECL_IMPORT
    #endif


    It looks like ,if child uses the same define as parent then parent class gets __declspec(dllimport) and we have such a error like LNK2001, why it was normally for QT3 - I think some changes for QObject are resulted in an error for old defines.
    Last edited by dresha48; 11th May 2011 at 13:48.
    Reply With QuoteReply With Quote
  12. #12
    dresha48 
    dresha48 is offlineBeginner
    Join Date
    Jan 2010
    Posts
    13
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: staticMetaObject

    Small addition:
    if you already have big project where you get such errors (I think it only could happens if you are changing yours projects from qt3 to qt4) - just use for parent classes different macro (not like for the children) , where you got errors - thats all . For exapmle I added for all parents which gives me LNK2001 error :
    add to parent classes from same dll ( in dll project property add to C/C++ ->Prprocessor->Preprocessor Definitions : DVL_DVL2_DLL_API; ):

    #include "dllDefines.h"

    class DVL_DVL2_API someParentClassName{...};

    dllDefines.h :

    #ifdef DVL_DVL2_DLL_API
    #define DVL_DVL2_API __declspec(dllexport)
    #else
    #define DVL_DVL2_API __declspec(dllimport)
    #endif
    Last edited by dresha48; 13th May 2011 at 11:35.
0 0