PDA

View Full Version : Plugin and shared class between plugin and application



wishper
18th August 2010, 14:55
Hi !
Well, I need to create a plugin manager, and some plugins to my application.
The goal of a plugin is to provide new items to the main application, extended from QGraphicsWidget with a few more methods and signals.
Since a plugin must be a pure interface, I realized one with some functions to communicate with the application.
Since the item is used by the application, but also need to be know by the plugin to create them, I include in the header of the plugin the declaration of the Item (it's a QGraphicsWidget with some pure virtual methods)

I manage to get my program and my plugin to compile. However, when I load the plugin, I get this error (came from pluginLoader.errorString() ) :

PluginManager : instance failed "Cannot load library /home/wishper/trunk/release/Plugins/lib_basicitems.so: (/home/wishper/trunk/release/Plugins/lib_basicitems.so: undefined symbol: _ZN4Item16staticMetaObjectE)"

Here is the light version of the header :


class Item : public QGraphicsWidget{
Q_OBJECT
public:
Item(QGraphicsItem * parent) : QGraphicsWidget(parent){};
~Item(){};
virtual bool isBackground() = 0;
virtual QList<PropertyInfo> getProperties() = 0;

signals:
void background(bool background);
void propertyUpdate();
};

class ItemCreator{
public:
~ItemCreator(){};
virtual Item * createItem(QByteArray init);
};

class Plugin
{
public:
virtual ~Plugin() {};
virtual QString getName() = 0;
virtual QList<QMenu * > getMenus() = 0;
virtual ItemCreator getItemCreator() = 0;
virtual QList<QByteArray *> getInitValues() = 0;
};

Q_DECLARE_INTERFACE(Plugin,
"fr.neticoa.xsimulbeta.plugin/1.0")


What I see with the error is that the problem came from the Item class. I really don't understand what is the problem. I tried many things, but the result is always the same.

Am I doing things wrong ?

Thanks a lot, regards.
wishper.

tbscope
19th August 2010, 05:38
Some obvious things to check:
1. Are all functions implemented?
2. Are the class definitions the same between the plugin and the program? (basically the first question again)
3. Can all libraries be found (I don't think that's the problem here)

By the way, did you check out the plugin examples in the documentation?

wishper
19th August 2010, 11:32
Well, I looked one more time. So yes, all my functions are implemented. The plugin and the application use the same header file, so it a yes for the second question.
And, yes too for the libraries.

But, there is hope ! After many tests, I succeed to load my plugin !
Apparently, the problem came from the Item definition. First, I need to declare it as an interface, and next I must remove the Q_OBJECT macro.
However, I can still extend the Item class from QGraphicsWidget, so the only drawback is for the signal (no macro, no signal ...), but I can use another interface to replace this, so it's not very bad.

I will let you know when my plugin will really work : I need to change some things in my program to be able to test the creation of items.

wishper
19th August 2010, 17:09
Finally it works !
So, the problem came from the Q_OBJECT macro, but it's seems that the fact that an interface is extended from a Qt class do not make problem.

For the signal, I found a solution, but it's a little .. dirty ?
In fact, since a signal is just a protected method, you can declare them in the interface, like a protected pure virtual method.
And in the class which implement the interface, you declare them as signal. (In fact, you don't ever need to declare them in the interface, but not do it seems far too dirty for me ;) )
I can't decide if this method is a good one or not, it works ... but it's really sound like a trick.

Regards.

totem
20th August 2010, 16:11
Hi

I don't really know if it will work for your plugin design (with your class being an interface), but I already extended a QGraphicsItem so it has signals/slots too, this way :



#ifndef _TSP_HANDLE_H_
#define _TSP_HANDLE_H_

#include <QObject>
#include <QGraphicsItem>


class Handle : public QObject, public QGraphicsItem
{
Q_OBJECT

Q_INTERFACES(QGraphicsItem)

public :
enum {Type = QGraphicsItem::UserType + 7};
virtual int type(void) const { return Handle::Type; }

public :
Handle(TSPScene *scene,int id,int state) ;

virtual QPainterPath shape(void) const ;
virtual QRectF boundingRect(void) const ;
virtual void paint(QPainter *painter,const QStyleOptionGraphicsItem *option,QWidget *) ;

signals :
void activated(int id,int s) ;
void deactivated(int id) ;
void updated(int id,const QPointF &cursorPos) ;
} ;

#endif // _TSP_HANDLE_H_


this code has been compiled, linked and executed successfully on windows.
If you want to try, let me know if it worked

wishper
23rd August 2010, 15:42
Well, I fear that this way won't work. In fact, you can't use the Q_OBJECT macro in the interface, since you must have only pure virtual method. And, with no Q_OBJECT macro, it became pretty hard to obtain signal.
In fact, before using plugin, I had declare my object almost like that : extending of a QGraphicsObject.

By the way, I was wondering what is the interest of your design ? What I mean is that there is the QGraphicsObject (fusion of a QGraphicsItem and a QObject) which provide a QGraphicsItem with slot and signals capabilities, why use your classes instead of this ?
I'm sure there is one, but I really don't see where :(

Regards.

totem
23rd August 2010, 16:38
Well yeah, I was afraid I missed something, but QGraphicsObject doc says :


This class was introduced in Qt 4.6.

And I'm still in 4.5.3 (waiting for 4.7) so here is the reason

Sorry for my previous answer, I should have read more carefully
Good luck !

yakin
23rd August 2010, 17:00
Isn't the symbol "_ZN4Item16staticMetaObjectE" generated by the meta object compiler (moc)?
Did you forget to link the generated moc_*.cpp file into your plugin? That would explain why the remove of Q_OBJECT would lead to success. Q_OBJECT requires the Implementations from the moc_x.cpp file.