Seite 1 von 1

QPluginLoader Fehler beim laden eines Plugins

Verfasst: 6. November 2010 20:17
von anno1988
Ich habe versucht mir ein Plugin zu schreiben und dieses dann mit dem QPluginLoader wieder in einer anderen Anwendung zu laden.

Allerdings funktioniert das nicht. Beim QPluginLoader Objekt bekomme ich folgende Fehlermeldung zurück:

Code: Alles auswählen

"Plugin verification data mismatch in '/home/me/libtestlib.so.1.0.0'" 
Das Plugin habe ich in einem C++Library Projekt des Qt Creators erstellt.

Weiß jemand was da der Fehler sein könnte?

Library:

testlib_global.h:

Code: Alles auswählen

#ifndef TESTLIB_GLOBAL_H
#define TESTLIB_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(TESTLIB_LIBRARY)
#  define TESTLIBSHARED_EXPORT Q_DECL_EXPORT
#else
#  define TESTLIBSHARED_EXPORT Q_DECL_IMPORT
#endif

#endif // TESTLIB_GLOBAL_H
testlib.h

Code: Alles auswählen

#ifndef TESTLIB_H
#define TESTLIB_H

#include "testlib_global.h"

class TESTLIBSHARED_EXPORT Testlib {

	public:
    Testlib();
		int getSum();


};

#endif // TESTLIB_H
testlib.cpp

Code: Alles auswählen

#include "testlib.h"


Testlib::Testlib() {



}


int Testlib::getSum() {

	return 888;

}


Konsolenprogramm:

Code: Alles auswählen

#include <QtCore/QCoreApplication>
#include <QPluginLoader>
#include <QDebug>

int main(int argc, char *argv[]) {

	QPluginLoader ploader;

	QCoreApplication a(argc, argv);



	ploader.setFileName("/home/me/libtestlib.so");


	if(ploader.load() == true) {

		if(ploader.isLoaded() == true) {

			qDebug() << "is loaded";

		}
		else {

			qDebug() << "not loaded";

		}

	}

	qDebug() << ploader.errorString();




	return a.exec();

}

Verfasst: 6. November 2010 21:52
von franzf
Du hast die Doku, speziell den Abschnitt "How to create Qt Plugins" (der in QPluginLoader verlinkt ist) nicht gelesen.
Eine simple shred-lib bringt dir nur was für QLibrary. Eine Klasse für so ein Qt Plugin muss von QObject erben. Auch Qt muss sich an C++ halten, und wenn die Klasse nicht von QObject erbt, wie soll aus der Instanz plötzlich ein QObject werden? Oder kann Qt zaubern? Schau mal was QPluginLoader::instance() zurück gibt!
Alle Lilnks, die unter "see also" angegeben werden sind auch interessant, vor allem das Example...

Verfasst: 6. November 2010 22:47
von anno1988
Also wenn ich das richtig verstanden habe ist die QLibrary Klasse nur dafür da shared libs direkt beim Linken einzubinden.

Bei einem Plugin muss ich dann allerdings die "Lower-Level API" http://doc.trolltech.com/4.7/plugins-howto.html benutzen, wenn ich Plugins für ein Konsolenprogramm schreiben will. Zusätzlich dann noch Interfaces schreibne und nach der Anleitung der Lower level API die Struktur des Plugins aufbauen.

Das muss ich dann mal ausprobieren.

Verfasst: 7. November 2010 00:09
von anno1988
Ok, ich habe mal versucht das Interface zu schreiben und das Plugin zu komplilieren. Allerdings bekomme ich hier schon Fehlermeldungen, obwohl es so eigentlich in der Anleitung steht.

Code: Alles auswählen

../testlib/testlib.h:13: Error: Undefined interface

TestLibInterface.h:

Code: Alles auswählen


#ifndef TESTLIBINTERFACE_H
#define TESTLIBINTERFACE_H

#include <QtPlugin>


class TestLibInterface {

	public:
		virtual ~TestLibInterface() {}

		virtual int getSum();

};




#endif // TESTLIBINTERFACE_H

testlib.h:

Code: Alles auswählen


#ifndef TESTLIB_H
#define TESTLIB_H

#include <QObject>
#include <QtPlugin>

#include "testlib_global.h"

#include "TestLibInterface.h"

class TESTLIBSHARED_EXPORT Testlib : public QObject, public TestLibInterface {

	Q_OBJECT
	Q_INTERFACES(TestLibInterface);

	public:
		Testlib(QObject *parent = 0);
		int getSum();


};


#endif // TESTLIB_H


testlib_global.h:

Code: Alles auswählen

#ifndef TESTLIB_GLOBAL_H
#define TESTLIB_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(TESTLIB_LIBRARY)
#  define TESTLIBSHARED_EXPORT Q_DECL_EXPORT
#else
#  define TESTLIBSHARED_EXPORT Q_DECL_IMPORT
#endif

#endif // TESTLIB_GLOBAL_H


testlib.cpp:

Code: Alles auswählen

#include "testlib.h"


Testlib::Testlib(QObject *parent) : QObject(parent) {



}


int Testlib::getSum() {

	return 888;

}

Q_EXPORT_PLUGIN2(pnp_extrafilters, Testlib)



testlib.pro:

Code: Alles auswählen

QT       -= gui

TARGET = $$qtLibraryTarget(pnp_extrafilters)

TEMPLATE = lib
CONFIG       += plugin

DEFINES += TESTLIB_LIBRARY

SOURCES += testlib.cpp

HEADERS +=\
        testlib_global.h \
    TestLibInterface.h \
    testlib.h

Verfasst: 7. November 2010 08:26
von franzf
Doku bitte lesen und nicht nur überfliegen - ist ja kein Flugsimulator...
Dir fehlt im Interface-header noch ein entsprechendes "Q_DECLARE_INTERFACE"-Statement.
Z.B.:

Code: Alles auswählen

Q_DECLARE_INTERFACE(TestLibInterface, "org.qt.test.TestLibInterface")

Verfasst: 7. November 2010 12:28
von anno1988
danke für die Hilfe. Jetzt funktioniert das Laden des Plugins.

Verfasst: 7. November 2010 12:30
von franzf
anno1988 hat geschrieben:danke für die Hilfe. Jetzt funktioniert das Laden des Plugins.
Das wundert mich aber. Bekommst du keine Meldung wg. "undefined symbol" o.Ä.? Denn dein "Interface" ist kein solches, es besitzt nämlich eine Deklaration einer nicht-pure-virtual Methode (getSum) welche nirgends implementiert wird. Mach ein "=0" bei der Deklaration hinten ran und es sollte passen.

Verfasst: 7. November 2010 14:01
von anno1988
ja, das habe ich bereits drin gehabt und das Interface abstrakt zu machen. Bei mir lokal zumindest.