QPluginLoader Fehler beim laden eines Plugins

Alles rund um die Programmierung mit Qt
Antworten
anno1988
Beiträge: 280
Registriert: 23. Januar 2009 20:49

QPluginLoader Fehler beim laden eines Plugins

Beitrag 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();

}
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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...
anno1988
Beiträge: 280
Registriert: 23. Januar 2009 20:49

Beitrag 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.
anno1988
Beiträge: 280
Registriert: 23. Januar 2009 20:49

Beitrag 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
Dateianhänge
test_projekt.zip
Projekt mit der Library und dem TestProgramm dafür.
(61.08 KiB) 133-mal heruntergeladen
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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")
anno1988
Beiträge: 280
Registriert: 23. Januar 2009 20:49

Beitrag von anno1988 »

danke für die Hilfe. Jetzt funktioniert das Laden des Plugins.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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.
anno1988
Beiträge: 280
Registriert: 23. Januar 2009 20:49

Beitrag von anno1988 »

ja, das habe ich bereits drin gehabt und das Interface abstrakt zu machen. Bei mir lokal zumindest.
Antworten