[gelöst] Plugins, MetaObjectSystem u. Zugr. auf Q_CLASSINFO

Alles rund um die Programmierung mit Qt
Antworten
kowi1134
Beiträge: 120
Registriert: 1. Mai 2005 17:48
Wohnort: Arnsberg

[gelöst] Plugins, MetaObjectSystem u. Zugr. auf Q_CLASSINFO

Beitrag von kowi1134 »

Dieses Problem ist hier gelöst worden: http://qtforum.de/forum/viewtopic.php?p=25601#25601

--------------------------------------------------------------------------------

Hallo zusammen!

Mein Problem ist etwas kniffliger, deshalb beschreibe ich zuerst mal meine Überlegungen und welchen Weg man zur Lösung schon mal nicht einschlagen kann. Die eigentliche Frage ist unten fett markiert.

In einem aktuellen Projekt von mir benutze ich erfolgreich Plugins, um die Fähigkeiten meines Programms zu erweitern.

Plugins leiten sich ja bekanntlich von einer Klasse ab, die ausschließlich rein virtuelle Methoden enthält.

(Da mein Hauptprogramm, welches die Plugins zur Laufzeit läd, aber nur die Methoden kennt, welche in der Interface-Klasse des Plugins beschrieben sind, arbeite ich auch nur mit diesen Methoden.)

Die die Interface-Klasse implementierenden Plugin-Klassen leiten sich ja außerdem von QObject ab und besitzen somit die Fähigkeiten eines QMetaObjects.

Hier mal ein paar Code-Fragment von den wichtigsten Klassen:

Code: Alles auswählen

class PluginInterface
{
public:
    PluginInterface {}
    virtual void setup() = 0;
};

Q_DECLARE_INTERFACE(PluginInterface, "de.meineDomain.PluginInterface/1.0")

Code: Alles auswählen

#include "PluginInterface.h"
#include <QObject>

class Plugin : public QObject, public PluginInterface 
{
    Q_OBJECT
    Q_INTERFACES(PluginInterface)
    Q_CLASSINFO("author", "kowi1134")
    Q_CLASSINFO("url", "http://not.needed.com")
public:
    void setup();
};

Code: Alles auswählen

#include <QtPlugin>
#include "Plugin.h"

void Plugin::setup()
{
    // ...
}

Q_EXPORT_PLUGIN2(plugin, Plugin)
Hier nun meine Frage(n):

Normalerweise ist ein Zugriff auf die Q_CLASSINFO der Plugin-Klasse ja wie folgt möglich.

Code: Alles auswählen

Plugin * plugin = new Plugin;

const QMetaObject * metaObj = plugin->metaObj();
int  authorIdx = metaObj->indexOfClassInfo("author");
QMetaClassInfo info = metaObj->classInfo(authorIdx);
cout << "Autor der Klasse Plugin: " << info.value();
Wie man sich aber denken kann, kenne ich die Klasse Plugin zur Kompilierzeit aber noch nicht, sondern nur das Interface (PluginInterface). Ein nahe liegende Möglichkeit zur Lösung des Problems bestünde also darin, einfach auf der Basis von PluginInterface zu arbeiten:

Code: Alles auswählen

QPluginLoader pluginLoader("plugin.dll");
QObject *obj = pluginLoader.instance();
PluginInterface * plugin = qobject_cast<PluginInterface *>(obj);

const QMetaObject * metaObj = plugin->metaObj();
int authorIdx = metaObj->indexOfClassInfo("author");
QMetaClassInfo info = metaObj->classInfo(authorIdx);
cout << "Autor der Klasse Plugin: " << info.value();
Dass das nicht geht, sehe ich ein, da sich die Klasse PluginInterface ja nicht von QObject ableitet und folglich auch nichts von QMetaObjects weiß.

Aber wie kann ich sonst auf die Q_CLASSINFO Einheiten der Klasse Plugin zugreifen, wenn ich die Klasse Plugin zur Kompilierzeit noch gar nicht kenne und mir nur das PluginInterface bekannt ist?

Vielen Dank für eure Aufmerksamkeit
kowi
Zuletzt geändert von kowi1134 am 23. September 2007 13:23, insgesamt 3-mal geändert.
kowi1134
Beiträge: 120
Registriert: 1. Mai 2005 17:48
Wohnort: Arnsberg

Beitrag von kowi1134 »

Ok, auch wenn es mir etwas peinlich ist, hier die Lösung (vielleicht hilft sie ja jemandem).

Wenn ich irgendeine Schnittstelle aus dem PluginInterface anspreche,
benutze ich den gecasteten plugin Zeiger, ansonsten für die QMetaObject Geschichten benutze ich ein ungecastes QObject (den obj Zeiger).

Code: Alles auswählen

// Plugin laden
QPluginLoader pluginLoader("plugin.dll");
QObject *obj = pluginLoader.instance();

// Das PluginInterface ansprechen (das QObject casten)
PluginInterface * plugin = qobject_cast<PluginInterface *>(obj);
plugin->setup();

// Das QMetaObject ansprechen (obj verwenden)
const QMetaObject * metaObj = obj->metaObj();
int authorIdx = metaObj->indexOfClassInfo("author");
QMetaClassInfo info = metaObj->classInfo(authorIdx);
cout << "Autor der Klasse Plugin: " << info.value();
Zum Abschluss möchte ich noch sagen, dass Plugins mit Qt echt super sind! hihi
Antworten