| Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date | |
| All threads index page 4 | |
Qt!
Th plugin does not load.
It is desired to implement a factory within a plugin. So that it is possible
to create as many instances of the object embedded in the plugin as
required.
Maybe one cannot declare annother class (here BP) in the interface class for
the plugin ?!?
Because when I omit the BP class declaration and the getBP method in
BPInterface the plugin load without problems.
The problem is best described by the source code, no? Here it is:
Merry Christmas!!
Frank
bpinterface.h
--------------------------------------------------------
class BP: public QObject
{
Q_OBJECT
public:
QString getName();
};
class BPInterface: public QObject
{
public:
virtual ~BPInterface() {}
virtual BP * getBP() = 0;
virtual QString getName() = 0;
};
Q_DECLARE_INTERFACE(BPInterface,"Amatel.BPInterface/1.0")
main.cpp
--------------------------------------------------------
#include "bpinterface.h"
void loadBP( QString fileName )
{
qDebug() << "loadBP()" << fileName;
QPluginLoader loader(fileName);
QObject *plugin = loader.instance();
if (plugin) {
BPInterface * bp;
bp = qobject_cast<BPInterface *>(plugin);
if (bp) {
qDebug() << "plugin loaded";
}
}
else
qDebug() << "Mixer::loadBP() FAILED: " << fileName;
}
void loadBPdir( QString dirName )
{
QDir pluginsDir(dirName);
foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
loadBP( pluginsDir.absoluteFilePath(fileName) );
}
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
loadBPdir("bp");
return app.exec();
}
bp1.h
--------------------------------------------------------
#include <bpinterface.h>
class BP1Plugin: public BPInterface
{
Q_OBJECT
Q_INTERFACES(BPInterface)
public:
BP * getBP();
QString getName();
};
bp1.cpp
--------------------------------------------------------
#include "bp1.h"
QString BP1Plugin::getName()
{
return QString("BP1");
}
BP * BP1Plugin::getBP()
{
BP * bp = new BP();
return bp;
}
QString BP::getName()
{
return QString("BP 1");
}
Q_EXPORT_PLUGIN2(bp1, BP1Plugin)
bp1.pro
--------------------------------------------------------
TEMPLATE = lib
CONFIG += plugin debug_and_release
INCLUDEPATH += ../../app
HEADERS = bp1.h
SOURCES = bp1.cpp
TARGET = bp1
DESTDIR = ../../../bin/bp
--
[ signature omitted ]
Hi again!! I managed to load the plugin. The solution was to include "bpinterface.h" in the HEADERS variable in "bp1.pro". But now the linker compains: main.o: In function `main': fac/src/app/main.cpp:68: undefined reference to `BP::getName()' collect2: ld returned 1 exit status The error ocurrs only if in main() a method of the factured class is called. To reproduce this I attached a fac.tgz in this Mail. > tar xvfz fac.tgz > cd fac > qmake -r > make > bin/fac Any suggestions?? Frank --------------------- files: . ./bin ./bin/bp ./src ./src/bp ./src/bp/bp1 ./src/bp/bp1/bp1.h ./src/bp/bp1/bp1.cpp ./src/bp/bp1/bp1.pro ./src/bp/bp.pro ./src/app ./src/app/main.cpp ./src/app/bpinterface.h ./src/app/app.pro ./src/src.pro ./fac.pro
Attachment:
Attachment:
fac.tgz
Attachment:
signature.asc
Description: GNU Zip compressed data
Message 3 in thread
Hey, I didn't know that attachments are not allowed.
So I uploaded it to my account:
http://www-zeuthen.desy.de/~fwinter/fac.tgz
Just do a qmake -r and make.
To reproduce the linker error, uncomment line 68 in main.cpp:
//qDebug() << bp->getName();
It is really clean code and uses an easy to understand structure. So If
someone managed to have a factory in a QPlugin, please tell me what's wrong
here.
Greetings,
Frank
--
[ signature omitted ]
Message 4 in thread
Frank wrote:
>To reproduce the linker error, uncomment line 68 in main.cpp:
> //qDebug() << bp->getName();
>
>It is really clean code and uses an easy to understand structure. So If
>someone managed to have a factory in a QPlugin, please tell me what's
> wrong here.
The problem is that you're using a *plugin*.
As such, by definition, you load it at runtime. You don't link to it.
So you *cannot* use something defined in the plugin from the main
application. You can only use the Qt plugin loading classes (and other
similar API) to obtain symbols you want.
--
[ signature omitted ]
Description: This is a digitally signed message part.
Message 5 in thread
Thiago,
does this mean, that it is in general impossible to realize a factory within
a plugin. "Factory" here means: I want to create more than one instance of
the loaded class (loaded as plugin).
Why do I want that? The loaded class represents a data reader, that is
queried multiple times for data simultanously. So I want to have different
instances of the data reader living in different threads to reply to these
request.
Greetings!
Frank
Thiago Macieira wrote:
> Frank wrote:
>>To reproduce the linker error, uncomment line 68 in main.cpp:
>>//qDebug() << bp->getName();
>>
>>It is really clean code and uses an easy to understand structure. So If
>>someone managed to have a factory in a QPlugin, please tell me what's
>> wrong here.
>
> The problem is that you're using a *plugin*.
>
> As such, by definition, you load it at runtime. You don't link to it.
>
> So you *cannot* use something defined in the plugin from the main
> application. You can only use the Qt plugin loading classes (and other
> similar API) to obtain symbols you want.
--
[ signature omitted ]
Message 6 in thread
Frank,
Factories are how I do all my plugins. I like to have the flexibility of creating multiple instances as well.
I know you have some of these done already, but here are the rules for Qt plugins:
The interface must not inherit QObject.
The interface must have no statics.
The interface must be declared with the Q_DECLARE_INTERFACE macro
The implementions of the interface must inherit multiply from QObject and the inteface
The impl must inherit QObject 1st. Moc needs it 1st in the inheritance list
The impl must use the Q_OBJECT macro and the Q_INTERFACES macro
The impls must be delcared as plugins using the Q_EXPORT_PLUGIN2 macro
The headers in each .pro must be in the HEADERS line as they need to be run through moc.
Good luck,
Justin Noel
Sr. Consulting Engineer
ICS
http://ics.com
Sent from my BlackBerry® wireless device
-----Original Message-----
From: Frank <frank.t.winter@xxxxxxxxx>
Date: Tue, 25 Dec 2007 18:39:42
To:qt-interest@xxxxxxxxxxxxx
Subject: Re: factory within plugins
Thiago,
does this mean, that it is in general impossible to realize a factory within
a plugin. "Factory" here means: I want to create more than one instance of
the loaded class (loaded as plugin).
Why do I want that? The loaded class represents a data reader, that is
queried multiple times for data simultanously. So I want to have different
instances of the data reader living in different threads to reply to these
request.
Greetings!
Frank
Thiago Macieira wrote:
> Frank wrote:
>>To reproduce the linker error, uncomment line 68 in main.cpp:
>>//qDebug() << bp->getName();
>>
>>It is really clean code and uses an easy to understand structure. So If
>>someone managed to have a factory in a QPlugin, please tell me what's
>> wrong here.
>
> The problem is that you're using a *plugin*.
>
> As such, by definition, you load it at runtime. You don't link to it.
>
> So you *cannot* use something defined in the plugin from the main
> application. You can only use the Qt plugin loading classes (and other
> similar API) to obtain symbols you want.
--
[ signature omitted ]