PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mehrere Instanzen von ein Plugin erzeugen



xmarvel
11-12-2005, 21:06
Hi,

Wieso erzeugt QPluginLoader::instance() in Qt4 nicht mehre Instanzen vom Plugin?

Hier mal der Beispiel Code:


bool loadPlugin(const QString& fileName)
{
bool isLoad = false;

QPluginLoader loader(fileName);

QObject *plugin = loader.instance();

if (plugin)
{
CShapeInterface *shape = qobject_cast<CShapeInterface*>(plugin);
if (shape)
{
qDebug("Pointer %p", &shape);
isLoad = true;
}
else qWarning("Konnte Plugin nicht casten!");

}
else qWarning("Konnte Plugin nicht laden");

return isLoad;
}

void testPlugin()
{
loadPlugin("libfoo.so");
// Ausgabe: Pointer 0xbfa0fdbc

loadPlugin("libfoo.so");
// Ausgabe: Pointer 0xbfa0fdbc
}


Nun leider erzeugt er nur eine Instanz irgendein Fehler wird auch nicht angezeigt. Wie kann ich jetzt mehrere Objekte vom selben Plugin erzeugen?

MfG
xmarvel

anda_skoa
12-12-2005, 10:20
instance() klingt wie eine Singleton Methode, also speziell für nur immer die selbe Instanz.

Vermutlich ist es besser, wenn du als Pluginklasse eine Factory machst, die dann nach von dir gewählter Strategie Instanzen von beliebigen Klassen machen kann.

Also in etwa


QObject *plugin = loader.instance();
if (plugin)
{
MyFactory* factory = qobject_cast<MyFactory*>(plugin);
if (factory)
{
CShapeInterface *shape = factor->createShape();
}
}


Ciao,
_

xmarvel
12-12-2005, 18:57
hi anda_skoa,

eine Factory Klasse noch nie was davon gehört aber nach wiki artikel versuch ich das mal umzusetzen.

Ich erstelle jetzt eine Klasse MyFactory


class MyFactory
{
public:
CShapeInterface* createShape()=0;
};


Dann meine bereits vorhandene Interface vom Plugin



class CShapeInterface : public MyFactory
{
public:
CShapeInterface*createShape()=0;
void draw()=0;
//...
};


Dann in mein Plugin



class Plugin : public CShapeInterface
{
public:
CShapeInterface* createShape()
{
return new Plugin();
}

void draw()
{
// foobar
}
};


Hab ich das richtig verstanden?

Thx
xmarvel

anda_skoa
14-12-2005, 14:49
Ja, zum Beispiel

Oder so



class CShapeInterface
{
public:
void draw() = 0;
};

class MyFactory : public QObject // oder eben die QPlugin Basisklasse
{
public:
CShapeInterface* createShape();
// oder
CShapeInterface* createShape(const QString& shapeName);
};


D.h. ein Plugin kann ja auch mehrere Shapes erzeugen können.

Ciao,
_

xmarvel
14-12-2005, 15:40
sry wenn ich jetzt nochmal doof nachfrage aber das hiese ja jedes Plugin hätte eine eigene Factory Klasse oder?
Wo der Plugin Schreiber seine Klassen "einsetzt" also würde ich die Methode createShape() benutzen wenn es nur eine Klasse geben soll im Plugin und die andere Klasse createShape(const QString&) wenn das Plugin mehrere Klassen hat also z.B. würde ein Plugin mit mehreren Klassen so aussehen:



class MyPluginClassLine() : public CShapeInterface
{
public:
void draw();
// ...
};

class MyPluginClassRectangle() : public CShapeInterface
{
public:
void draw();
// ...
};

class MyFactory
{
public:
CShapeInterface* createShape(const QString& shapeName);
{
if (shapeName == "line")
return new MyPluginClassLine();
if(shapeName == "rectangle")
return new MyPluginClassRectangle();

//usw.
}
};


oder das Konzept des Plugin ist das es nur eine Klasse ist müsste dann z.B. so aussehen.



class MySuperAllInOnePluginClass() : public CShapeInterface
{
public:
void draw();
// ...
};

class MyFactory
{
public:
CShapeInterface* createShape();
{
return new MySuperAllInOnePluginClass();
}
};

Obwohl ich dann hier denke das eine Methode in der Klasse doch aussreicht wozu dann hier extra eine Factory Klasse?

MfG
xmarvel

anda_skoa
14-12-2005, 16:10
Ja, korrekt.

Meistens erlaubt man mehr als eine Klasse aus einem Plugin zu laden, weil man dann nicht für jedes Element ein eigenes Plugin braucht.

Du brauchst nicht unbedingt eine Factory, du könntest auch in deiner Shape Basis eine Methode newInstance() oder clone() machen, die eine neue Instanz eben dieser Klasse macht, potentiell mit einer Kopie der Inhalte.

Ciao,
_

xmarvel
14-12-2005, 18:48
danke für die Erklärung jetzt müsste ich es verstanden haben.

MfG
xmarvel