Inheritance of plugins with QPluginLoader not working?



  • Hello everybody,

    I am having some major issues with inheritance in between plugins and the ability
    to load/cast them properly at runtime. Let me describe the problem. I will also provide
    the whole project tree so you can try it out yourself.

    I have two interfaces: Parent/ChildInterface, linked by a natural inheritance relation:
    @
    class ParentInterface{};
    Q_DECLARE_INTERFACE(ParentInterface, "ParentInterface/1.0")
    class ChildInterface : public ParentInterface{};
    Q_DECLARE_INTERFACE(ChildInterface, "ChildInterface/1.0")
    @

    Then I have two plugins (PluginChild/Parent), each respectively implementing the
    corresponding interface:
    @
    class PluginChild : public QObject, public ChildInterface{ //...
    class PluginParent : public QObject, public ParentInterface{ //...
    @

    Now I load the plugins at runtime using what follows:
    @
    QObject *plugin = loader.instance();
    if( plugin ){
    qDebug() << "==> Loaded correct QPlugin";

            ChildInterface*  iC = qobject_cast<ChildInterface*>(plugin);
            if(iC) qDebug() << "==> ChildInterface CASTED";
            else   qDebug() << "==> ChildInterface FAILED";            
            
            ParentInterface* iP = qobject_cast<ParentInterface*>(plugin);
            if(iP) qDebug() << "==> ParentInterface CASTED";
            else   qDebug() << "==> ParentInterface FAILED";
        } else
            qDebug() << "==> Load incorrect QPlugin";
    

    @

    And this is the output I get:
    @
    Loading: "/Users/ata2/workspace/starlab/tester/plugins/libplugin_child.dylib"
    ==> Loaded correct QPlugin
    ==> ChildInterface CASTED
    ==> ParentInterface FAILED
    Loading: "/Users/ata2/workspace/starlab/tester/plugins/libplugin_parent.dylib"
    ==> Loaded correct QPlugin
    ==> ChildInterface FAILED
    ==> ParentInterface CASTED
    @

    The question is simple: why libplugin_child fails during casting ParentInterface?
    The full source tree is available in a compressed zip "HERE":http://www.sfu.ca/~ata2/tester.zip

    Thank you so much for your input

    Andrea Tagliasacchi



  • You are most probably missing a Q_INTERFACES(ParentInterface) in your PluginChild.

    qobject_cast() relies on the information provided by the meta object system, which requires you to specify any implemented interfaces using Q_INTERFACES() (and all QObject classes to specify Q_OBJECT). ParentInterface and ChildInterface are not QObjects and so there is no meta object information (and thus qobject_cast() cannot work).

    However, ParentInterface is still a parent class of ChildInterface (in terms of C++ inheritance). So once you have cast a plugin to ChildInterface using qobject_cast(), you can cast it to ParentInterface implicitly or explicitly using static_cast().
    @
    ChildInterface* iC = qobject_cast<ChildInterface*>(plugin);
    ParentInterface* iP = static_cast<ParentInterface*>(iC);
    @



  • Thanks Lukas, I understand the problem. The source of it was in the full project.
    In there I had the following

    @
    class SurfaceMeshIO : public ModelIO{
    Q_INTERFACES(ModelIO)
    ...
    @

    @ // Source of error
    class io_surfacemesh_off : public QObject, public SurfaceMeshIO{
    Q_OBJECT
    Q_INTERFACES(SurfaceMeshIO)
    ....
    @

    I was assuming that since "io_surfacemesh_off" inherited from SurfaceMeshIO, the Q_INTERFACE(ModelIO) was already taken care of from its superclass. I have to admit, it's kind of weird that I have to do what follows:

    @ // Correction
    class io_surfacemesh_off : public QObject, public SurfaceMeshIO{
    Q_OBJECT
    Q_INTERFACES(SurfaceMeshIO)
    Q_INTERFACES(ModelIO)
    ....
    @


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.