Results 1 to 14 of 14

Thread: Multiple inherittance in plugins

  1. #1
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Multiple inherittance in plugins

    I'm hitting a wall here. I have a plugin interface that needs signals and slots (so must subclass QObject and have the Q_OBJECT macro), then my subclasses (or my plugins, as it were) need to inherit both my interface and either QWidget or something similar (like QGLWidget).

    Unfortunately, when I inherit both my interface and QWidget, my compiler is telling me that QObject is an ambiguous base of my plugin. This appears to stem from the Q_EXPORT_PLUGIN2() macro. Here's the exact compiler output:
    Quote Originally Posted by gcc
    evilcpcMenuAeon.cpp: In function 'QObject* qt_plugin_instance()':
    evilcpcMenuAeon.cpp:33: error: 'QObject' is an ambiguous base of 'evilcpcMenuAeon'
    /usr/include/qt4/QtCore/qpointer.h: In member function 'QPointer<T>::operator T*() const [with T = evilcpcMenuAeon]':
    evilcpcMenuAeon.cpp:33: instantiated from here
    /usr/include/qt4/QtCore/qpointer.h:58: error: 'QObject' is an ambiguous base of 'evilcpcMenuAeon'
    /usr/include/qt4/QtCore/qpointer.h: In member function 'QPointer<T>& QPointer<T>::operator=(T*) [with T = evilcpcMenuAeon]':
    evilcpcMenuAeon.cpp:33: instantiated from here
    /usr/include/qt4/QtCore/qpointer.h:48: error: 'QObject' is an ambiguous base of 'evilcpcMenuAeon'
    /usr/include/qt4/QtCore/qpointer.h:48: error: 'QObject' is an ambiguous base of 'evilcpcMenuAeon'
    make[1]: *** [release/evilcpcMenuAeon.o] Error 1
    make[1]: Leaving directory `/home/rich/svn/evilcpc/trunk/plugins/menu/aeon'
    make: *** [release] Error 2
    Is there any way around this?
    Life without passion is death in disguise

  2. #2
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Multiple inherittance in plugins

    Quote Originally Posted by KShots View Post
    I'm hitting a wall here. I have a plugin interface that needs signals and slots (so must subclass QObject and have the Q_OBJECT macro), then my subclasses (or my plugins, as it were) need to inherit both my interface and either QWidget or something similar (like QGLWidget).

    Unfortunately, when I inherit both my interface and QWidget, my compiler is telling me that QObject is an ambiguous base of my plugin. This appears to stem from the Q_EXPORT_PLUGIN2() macro. Here's the exact compiler output:Is there any way around this?
    I think I've already answered this in another threads of yours but anyway :
    1. plugin interfaces must be abstract classes (so no inheritance from non-abstract classes, and especially not from QObject)
    2. multiple inheritance needs so called virtual inheritance in ancestor classes
    3. by design, multiple inheritance from QObject is IMPOSSIBLE so just forget about it and find another design...
    Hope this helps.
    Current Qt projects : QCodeEdit, RotiDeCode

  3. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    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: Multiple inherittance in plugins

    Be careful when you use the term "virtual inheritance". Multiple inheritance doesn't require virtual inheritance.

  4. #4
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Multiple inherittance in plugins

    Quote Originally Posted by wysota View Post
    Be careful when you use the term "virtual inheritance". Multiple inheritance doesn't require virtual inheritance.
    Is there a misunderstanding here??? By "virtual inheritance" I mean use of "virtual" keyword in front of regular inheritance declaration which is needed to disambiguate names in case of multiple inheritance... This little FAQ section might be clearer than my poor explanations anyway...
    Current Qt projects : QCodeEdit, RotiDeCode

  5. #5
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Multiple inherittance in plugins

    Quote Originally Posted by fullmetalcoder View Post
    I think I've already answered this in another threads of yours but anyway :
    1. plugin interfaces must be abstract classes (so no inheritance from non-abstract classes, and especially not from QObject)
    2. multiple inheritance needs so called virtual inheritance in ancestor classes
    3. by design, multiple inheritance from QObject is IMPOSSIBLE so just forget about it and find another design...
    Hope this helps.
    Hmm... so in this case I should attempt to use boost signals and slots rather than Qt signals and slots for my plugin interface? The only reason I wanted QObject was for signals and slots.

    Alternatively, I suppose I could put the signals and slots into my plugin classes and use QMetaObject to parse all the available methods for signals and slots... but that seems a lot of effort. Any other way of doing something similar?
    Last edited by KShots; 20th April 2007 at 19:46.
    Life without passion is death in disguise

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    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

    Quote Originally Posted by fullmetalcoder View Post
    Is there a misunderstanding here??? By "virtual inheritance" I mean use of "virtual" keyword in front of regular inheritance declaration which is needed to disambiguate names in case of multiple inheritance...
    This only applies if the superclasses both inherit another (the same) class and by itself it doesn't yet mean virtual inheritance is required.

    Qt Code:
    1. class A{};
    2. class B{};
    3. class C : public A, public B {}; // this doesn't require "virtual" anywhere
    4. class D : public A{};
    5. class E : public C, public D{}; // this doesn't _require_ A to be "virtual" in C and D
    6. // but it might be needed depending on how you use the classes
    To copy to clipboard, switch view to plain text mode 

    Quote Originally Posted by KShots View Post
    Hmm... so in this case I should attempt to use boost signals and slots rather than Qt signals and slots for my plugin interface? The only reason I wanted QObject was for signals and slots.
    The plugin itself doesn't have to inherit the actual functionality you require. It may simply return an instance of a class inheriting some common base.

    Qt Code:
    1. class Blah : public QObject { ... };
    2.  
    3. struct Plugin : public QObject, public SomeInterface{
    4. Q_OBJECT_AND_STUFF
    5. Blah *createInstance(QObject *parent=0){
    6. return new BlahSubclass(parent);
    7. }
    8. };
    To copy to clipboard, switch view to plain text mode 

  7. #7
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Multiple inherittance in plugins

    Quote Originally Posted by wysota View Post
    This only applies if the superclasses both inherit another (the same) class and by itself it doesn't yet mean virtual inheritance is required.

    Qt Code:
    1. class A{};
    2. class B{};
    3. class C : public A, public B {}; // this doesn't require "virtual" anywhere
    4. class D : public A{};
    5. class E : public C, public D{}; // this doesn't _require_ A to be "virtual" in C and D
    6. // but it might be needed depending on how you use the classes
    To copy to clipboard, switch view to plain text mode 
    Yeah, sure... But in the case we were discussing I implicitly pre-supposed MI to involve the same base...

    Quote Originally Posted by wysota View Post
    The plugin itself doesn't have to inherit the actual functionality you require. It may simply return an instance of a class inheriting some common base.

    Qt Code:
    1. class Blah : public QObject { ... };
    2.  
    3. struct Plugin : public QObject, public SomeInterface{
    4. Q_OBJECT_AND_STUFF
    5. Blah *createInstance(QObject *parent=0){
    6. return new BlahSubclass(parent);
    7. }
    8. };
    To copy to clipboard, switch view to plain text mode 
    This is not a solution... the reason for plugin interfaces to be abstract is that it frees the plugin from dependency to an intermediate library storing implementations of methods that would be defined in the interface... Using an abstract class limits the dependency to a single header file whereas using complex (i.e. non-abstract) classes that must be known to both the app and its plugins force to rely on an intermediate shared library which contains all base plugin classes specifications... (and believe me, this is not an easy way to go, even if its brings great power...)

    Quote Originally Posted by KShots
    Alternatively, I suppose I could put the signals and slots into my plugin classes and use QMetaObject to parse all the available methods for signals and slots... but that seems a lot of effort. Any other way of doing something similar?
    The use of QMetaObject is not required directly here... As the plugin instance creator returns a QObject you can just connect it as if signals/slots were defined in the base class (but then you just assume their presence and a badly implemented plugin could break this logic...)
    Current Qt projects : QCodeEdit, RotiDeCode

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    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: Multiple inherittance in plugins

    Quote Originally Posted by fullmetalcoder View Post
    This is not a solution... the reason for plugin interfaces to be abstract is that it frees the plugin from dependency to an intermediate library storing implementations of methods that would be defined in the interface...
    Strange, because Qt uses the exact same method for providing widget plugins for Designer... And as far as I know other component technologies (like COM) use that approach as well...

    Using an abstract class limits the dependency to a single header file whereas using complex (i.e. non-abstract) classes that must be known to both the app and its plugins force to rely on an intermediate shared library which contains all base plugin classes specifications... (and believe me, this is not an easy way to go, even if its brings great power...)
    But where does my approach violate any of the above mentioned statements? I don't see a problem for "Blah" being an abstract class declared in the same file as "SomeInterface"...

  9. #9
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Multiple inherittance in plugins

    Quote Originally Posted by wysota View Post
    Strange, because Qt uses the exact same method for providing widget plugins for Designer... And as far as I know other component technologies (like COM) use that approach as well...
    All the dependencies are NOT in Qt Designer itself but in Qt libs, including QtDesigner and QtDesignerComponents library...

    Quote Originally Posted by wysota View Post
    But where does my approach violate any of the above mentioned statements? I don't see a problem for "Blah" being an abstract class declared in the same file as "SomeInterface"...
    It will be OK as long as Blah inherits ONLY from Qt classes, or other external libraries BTW, (thus accessible from the plugin without the need to create an intermediary library) AND does not implement any method of its own (except inline methods and possibly, but might depend on compiler, methods implemented inside the header file).
    Current Qt projects : QCodeEdit, RotiDeCode

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    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: Multiple inherittance in plugins

    Quote Originally Posted by fullmetalcoder View Post
    All the dependencies are NOT in Qt Designer itself but in Qt libs, including QtDesigner and QtDesignerComponents library...
    The only dependency is QObject and obviously you need that anyway to create Qt plugins.

    It will be OK as long as Blah inherits ONLY from Qt classes, or other external libraries BTW, (thus accessible from the plugin without the need to create an intermediary library) AND does not implement any method of its own (except inline methods and possibly, but might depend on compiler, methods implemented inside the header file).
    I don't see how moving those "non-inline" methods to the interface class would help. And besides that's really not a problem - you can create a library with symbols needed by the plugin and you're there. Exactly like Qt and Designer do it.

  11. #11
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Multiple inherittance in plugins

    Quote Originally Posted by wysota View Post
    you can create a library with symbols needed by the plugin and you're there.
    Isn't that what I was saying??? Basically if your INTERFACE (which according to the docs should abstract) DOES IMPLEMENT some methods it may be necessary to create such an intermediary shared library with all the symbols that are used by both the app and plugins. Otherwise the headers are enough and that's the way suggested by the docs because it obviously make things MUCH simpler...

    Quote Originally Posted by wysota View Post
    Exactly like Qt and Designer do it.
    Designer does not have any problem because, as I've said already it is a wrapper app around several libraries (namely QtDesigner and QtDesignerComponents) and plugins.
    Current Qt projects : QCodeEdit, RotiDeCode

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    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: Multiple inherittance in plugins

    I don't really see a problem in doing this the way I said I made a few plugins in my life (both using and not using the Qt plugin framework) and they always worked as expected in the form I suggested. COM seems to work too, Java implementing interfaces seems to work, other languages as well... I don't really see a problem in creating an implementation of an interface that returns an instance of implementation of another interface...

    I think it should look more or less like so:
    Qt Code:
    1. struct MyInterface {
    2. virtual void method1() = 0;
    3. virtual void method2() const = 0;
    4. virtual int method3() = 0;
    5. virtual double method4(int) = 0;
    6. virtual ~MyInterface(){}
    7. };
    8.  
    9. struct PluginInterface {
    10. virtual ~PluginInterface(){}
    11. virtual MyInterface *create(QWidget *parent=0) = 0;
    12. };
    13. Q_DECLARE_INTERFACE(PluginInterface, "xxx")
    To copy to clipboard, switch view to plain text mode 

    And implementation:
    Qt Code:
    1. struct MyInterfaceImpl : public QObject, public MyInterface {
    2. MyInterfaceImpl(QWidget *parent = 0) : QObject((QObject*)parent){}
    3. void method1(){ printf("BLABLA\n"); }
    4. void method2() const { printf("BLABLA\n"); }
    5. int method3() { return 7; }
    6. double method4(int a) { return a*1.0/7.0; }
    7. ~MyInterfaceImpl(){}
    8. };
    9.  
    10. struct Plugin : public QObject, public PluginInterface {
    11. Q_OBJECT
    12. Q_INTERFACES(PluginInterface)
    13. Plugin(QObject *parent=0) : QObject(parent){}
    14. ~Plugin(){}
    15. MyInterface *create(QWidget *parent=0){ return new MyInterfaceImpl(parent); }
    16. };
    To copy to clipboard, switch view to plain text mode 

  13. #13
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Multiple inherittance in plugins

    Quote Originally Posted by wysota View Post
    I don't really see a problem in doing this the way I said I made a few plugins in my life (both using and not using the Qt plugin framework) and they always worked as expected in the form I suggested. COM seems to work too, Java implementing interfaces seems to work, other languages as well... I don't really see a problem in creating an implementation of an interface that returns an instance of implementation of another interface...
    I did NOT say this was a problem... Your example works pretty fine because both classes are INTERFACES and don't IMPLEMENT any method of their own... They just provide pur virtual methods that pligin implementation MUST subclass... What I pointed out as a source of trouble was non-abstract classes used as interfaces...

    Hope this make my explanations a little clearer...
    Current Qt projects : QCodeEdit, RotiDeCode

  14. #14
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    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: Multiple inherittance in plugins

    An interface is by definition a class that's pure abstract. And I don't consider a need to use an external library "trouble", by the way.

Similar Threads

  1. Qt plugins - how to do a libtool-style autoload
    By KShots in forum Qt Programming
    Replies: 2
    Last Post: 7th February 2007, 12:40
  2. Qt4 Plugins How-to
    By Chaid in forum Qt Programming
    Replies: 4
    Last Post: 8th July 2006, 08:32
  3. how to corss compile for windows in Linux
    By safknw in forum Qt Programming
    Replies: 24
    Last Post: 13th May 2006, 05:23
  4. Arthur Plugins demos and designer
    By antonio.r.tome in forum Installation and Deployment
    Replies: 4
    Last Post: 21st March 2006, 14:01
  5. Replies: 25
    Last Post: 15th January 2006, 00:53

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.