Results 1 to 10 of 10

Thread: qobject_cast fails across dynamic library boundaries

  1. #1
    Join Date
    Aug 2008
    Posts
    132
    Thanks
    23
    Thanked 3 Times in 3 Posts

    Default qobject_cast fails across dynamic library boundaries

    Hi

    I'm sitting with a problem where a qobject_cast fails when doing a cast across a DLL boundary.

    I have a base class:

    Qt Code:
    1. class Variable : public QObject
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. Variable(QObject* parent = 0);
    7. ~Variable();
    8. }
    To copy to clipboard, switch view to plain text mode 

    and a class which inherits Variable:
    Qt Code:
    1. class MatrixReal : public Variable
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. MatrixReal();
    7. }
    To copy to clipboard, switch view to plain text mode 

    I create a MatrixReal* instance and cast it to a Variable*. When casting Variable* to MatrixReal* again later on in the same DLL it works. However if I send this Variable* to a different DLL and try to cast to MatrixReal* there it fails.

    Any ideas on how to get this working would be much appreciated.

    Thanks,
    Jaco

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: qobject_cast fails across dynamic library boundaries

    Could you show relevant pieces of the code?
    J-P Nurmi

  3. #3
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: qobject_cast fails across dynamic library boundaries

    Search the forum for other threads on this topic.

    Make sure that the header of the class you wish to qobject_cast to, is not processed by moc in both the DLLs (i.e. it must not be in both .pro files' HEADERS sections).

  4. #4
    Join Date
    Aug 2008
    Posts
    132
    Thanks
    23
    Thanked 3 Times in 3 Posts

    Default Re: qobject_cast fails across dynamic library boundaries

    Hi

    Thanks for the response. I searched the forum and found a good post explaining the operation of qobject_cast and it explains why it fails.

    I also read on the proposed solutions there:
    1) Using inherits() : This will not work for me since I up from a base class to a class that inherits the base class. As I understand inherits() works the other way around?
    2) Creating a library with the classes in it. : I would use this as a last resort really.

    For now, I think I found a different solution using reinterpret_cast. It works for now, but I'm not sure if it will work if there are more child classes present. Let me first show my code:

    Qt Code:
    1. if (variable) {
    2. if (reinterpret_cast<MatrixReal*> (variable))
    3. QMessageBox::warning(0,"Cast successful","Cast successful");
    4. else
    5. QMessageBox::warning(0,"Cast failed","Cast failed");
    6. }
    To copy to clipboard, switch view to plain text mode 

    Now the question is, will this work if there is for example a MatrixComplex class as well? I would then have something like:

    Qt Code:
    1. if (variable) {
    2. if (reinterpret_cast<MatrixReal*> (variable))
    3. QMessageBox::warning(0,"Cast successful","Cast successful to real matrix");
    4. else if (reinterpret_cast<MatrixComplex*> (variable))
    5. QMessageBox::warning(0,"Cast successful","Cast successful to complex matrix");
    6. else
    7. QMessageBox::warning(0,"Cast failed","Cast failed");
    8. }
    To copy to clipboard, switch view to plain text mode 

    Will this still work? I guess the answer will be that this is a bad implementation since I read everywhere that reinterpret_cast is unsafe.

    If needed I can post more code and look at an alternative way of doing this. I can also give more details of why I need to do these casts in my application.

    Thanks,
    Jaco

  5. #5
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: qobject_cast fails across dynamic library boundaries

    reinterpret_cast does NOT check if the argument is of a type, but rather tells the compiler that "you (the user) knows what he is doing" and it should just treat the type as if it was of the type you are casting to.

    So, no, you may not replace a qobject_cast that way (except you are not interested in the testing part of the cast).

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: qobject_cast fails across dynamic library boundaries

    I believe that dynamic_cast -does- check that the argument is of the template type, and will return null if the cast fails. I've written some very hairy templated dynamic_cast code that depends on exactly this if / else if / else heirarchical behavior, and it works as expected - the dynamic casting cascades down the conditionals until one of the casts succeeds and returns a non-null result.

    Use of dynamic_cast<> does require that you compile with the right flags to turn on run time type identification if your compiler doesn't do it by default.

    As for qobject_cast, I have never quite understood why the trolls have felt the need to reinvent wheels that are already working quite well within the Standard C++ Library.

  7. #7
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: qobject_cast fails across dynamic library boundaries

    dynamic_cast does NOT (necessarily) work across shared libraries.
    From experience: when you (try to) dynamic_cast a templated-type across shared libs with gcc, you are in trouble.
    qobject_cast will work more often than dynamic_cast (usually). But (see threads) has its limitations, too.

  8. #8
    Join Date
    Aug 2008
    Posts
    132
    Thanks
    23
    Thanked 3 Times in 3 Posts

    Default Re: qobject_cast fails across dynamic library boundaries

    Thanks for all the replies.

    I actually have an identifier in my Variable base class which indicates which type of variable it is. Thus I will use this for the type checking and then do a reinterpret_cast once I know what type it is.

    This might not be the optimal way, but my Variable base class need to keep this information for other purposes as well, so I actually had all the information I needed without realizing it.

    Thanks again,
    Jaco

  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: qobject_cast fails across dynamic library boundaries

    Could you show us how exactly did you try to use qobject_cast? What does this return when called in both DLLs?

    Qt Code:
    1. qDebug() << "I am a " << MatrixReal::staticMetaObject().className();
    2. const QMetaObject *mo = MatrixReal::staticMetaObject().superClass();
    3. while(mo){
    4. qDebug() << "It's superClass is" << mo->className();
    5. mo = mo->superClass();
    6. }
    To copy to clipboard, switch view to plain text mode 

  10. #10
    Join Date
    Dec 2008
    Posts
    29
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: qobject_cast fails across dynamic library boundaries

    I didn't see your question thread, so I've described the reason and solution of your (my ) problem in separate thread..

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.