Seite 1 von 1
QT-Klasse in Dll auslagern... und wieder benutzen
Verfasst: 2. März 2007 15:32
von gerome69
Hallo zusammen,
mir fehlt der Link zu einem Tutorial für sowas. Tip dazu?!
Ich möchte halt gerne ein paar Standardklassen in eine DLL auslagern.
Was ich bisher versucht habe:
1. Mein DLL-Projekt:
qttestdll.pro:
Code: Alles auswählen
TEMPLATE = lib
QT -= gui
CONFIG += dll qt thread
TARGET +=
DEPENDPATH += .
INCLUDEPATH += .
DEFINES += BUILD_DLL
SOURCES += qttestdll.cpp
qttestdll.cpp
Code: Alles auswählen
#ifdef BUILD_DLL
#define EXPORT_DLL Q_DECL_EXPORT
#else
#define EXPORT_DLL
#endif
#include <QObject>
class EXPORT_DLL QtTest : public QObject {
Q_OBJECT
public:
QtTest() {printf("Class loaded!\n");}
inline ~QtTest(){};
void printOut() {printf("Print out function!\n");}
};
Das läßt sich auch wunderbar kompilieren und ich bekomme ein qttest.dll und eine qttestdll.a
Nur wir nutze ich das Ganze?
Ich habe folgendes versucht:
Code: Alles auswählen
[...]
QLibrary myLib("QtTestDll");
if (myLib.load()) printf("Loaded!\n"); else printf("Not loaded!\n");
typedef void (*MyPrototype)();
//MyPrototype myFunction = (MyPrototype) myLib.resolve("QtTest");
MyPrototype myFunction = (MyPrototype) myLib.resolve("QtTest::printOut");
if (myFunction) myFunction(); else printf("No Function\n");
printf("END!\n");
Wie nicht anders zu erwarten, bekomme ich immer "No Function".
Wie instanziere ich die Klasse aus der dll korrekt? Und wie greife ich auf deren Funktionen zu?
Danke für Tips, Bernd
QtTest::QtTest() {
printf("TEST\n");
}
void QtTest::printOut() {
printf("Test out!!!\n");
}
[/code]
Verfasst: 12. April 2007 23:17
von dontinelli
Obwohl der Thread schon uralt ist: Ich wäre auch an einer Lösung interessiert...
Cheers
Don Tinelli
Verfasst: 13. April 2007 09:42
von Christian81
Ich würde sagen - das Vorgehen ist das gleiche wie wenn man eine ganz normale andere Lib einbindet.
LIBS += mylib
INCLUDEPATH += /pfad/zu/headern
Verfasst: 13. April 2007 11:08
von lepsai
Dass, was du da versuchst kann nicht gehen. Funktionen innerhalb klassen gehören zur Klasseninstanz und können nicht unabhängig von einer solchen geladen werden. Der Weg ist:
Code: Alles auswählen
class QtTestFactory{
public:
virtual QtTest* createQtTestClass() const{return new QtTest();}
};
extern "C" declspec(dllexport) QtTestFactory* _cdecl GetClassFactory(){
return new QtTestFactory();
}
QLibrary myLib("QtTestDll");
if (myLib.load()) printf("Loaded!\n"); else printf("Not loaded!\n");
typedef QtTestFactory*(*MyPrototype)();
MyPrototype myFunction = (MyPrototype) myLib.resolve("GetClassFactory");
QtTestFactory* factory = myFunction();
QtTest* classInstance = factory->create();
übrigens, so funktioniert auch Q_PLUGIN_EXPORT() macro
Verfasst: 13. April 2007 16:58
von dontinelli
Und wie verwendet man die ganze Klasse und nicht nur eine einzelne Funktion?
Verfasst: 13. April 2007 17:32
von Christian81
dontinelli hat geschrieben:Und wie verwendet man die ganze Klasse und nicht nur eine einzelne Funktion?
Hast Du dich schonmal mit C/C++ Grundlagen beschäftigt? Wie verwendest Du z.B. QWidget ? Das ist auch nichts anderes...
Verfasst: 13. April 2007 17:51
von gerome69
Christian81 hat geschrieben:dontinelli hat geschrieben:Und wie verwendet man die ganze Klasse und nicht nur eine einzelne Funktion?
Hast Du dich schonmal mit C/C++ Grundlagen beschäftigt? Wie verwendest Du z.B. QWidget ? Das ist auch nichts anderes...
Ich finde die Frage überhaupt nicht unsinnig. Meine Ursprungsfrage war doch: wie instanziere ich eine Qt-Klasse als ganzes, die in einer dll ist.
Habe es inzwischen gelöst:
Code: Alles auswählen
qtestdll.h:
#ifndef QTTESTDLL_H
#define QTTESTDLL_H
#ifdef BUILD_DLL
#define EXPORT_DLL Q_DECL_EXPORT
#else
#define EXPORT_DLL
#endif
#include <QObject>
class EXPORT_DLL QtTest : public QObject {
Q_OBJECT
public:
QtTest();
inline ~QtTest(){};
void printOut();
};
#endif
qtestdll.cpp:
Code: Alles auswählen
#include "qttestdll.h"
QtTest::QtTest() {
printf("TEST\n");
}
void QtTest::printOut() {
printf("Test out!!!\n");
}
Daraus mit folgendem Projekt-File ein dll gebaut:
Code: Alles auswählen
TEMPLATE = lib
QT -= gui
CONFIG += dll qt thread
TARGET +=
DEPENDPATH += .
INCLUDEPATH += .
DEFINES += BUILD_DLL
HEADERS += qttestdll.h
SOURCES += qttestdll.cpp
Bekomme dann: QtTestDll.dll und libQtTestDll.a

mport-Library)
Dann ein neues Projekt zum Testen:
main.cpp:
Code: Alles auswählen
#include "qttestdll.h"
int main() {
QtTest *qtTest=new QtTest();
qtTest->printOut();
return 1;
}
Und im .pro-File:
Code: Alles auswählen
TEMPLATE = app
QT -= gui
CONFIG +=console
TARGET +=
DEPENDPATH += .
INCLUDEPATH += .
LIBS+=".\libQtTestDll.a"
SOURCES += main.cpp
Und voilà ich bekomme eine .exe, die die Klasse aus der dll instanziert! Das ganze ist nicht statisch gelinkt gegen die ".a". Sobald ich die dll umbenenne, sagt er, daß er wegen der fehlenden dll die Application nicht starten kann.
Gruß, Bernd
Verfasst: 13. April 2007 17:55
von Christian81
Nunja, das war doch gar nicht so schwer. Das Export-Macro könnte man noch etwas verbessern aber sonst ist es ok so.
Ach ja - den dtor zu inlinen ist auch keine gute Idee, schon gar nicht wenn man die Klasse dazu noch exportiert.
Verfasst: 13. April 2007 17:56
von gerome69
Christian81 hat geschrieben: Ach ja - den dtor zu inlinen ist auch keine gute Idee, schon gar nicht wenn man die Klasse dazu noch exportiert.
Ja klar, das war ja nur ne extrem kurze gefasste Version fürs Beispiel und zum Testen, kein praktisch relevanter Code.
Gruß, Bernd
Verfasst: 13. April 2007 19:16
von dontinelli
Vielleicht steht bei mir ein elefant auf dem Schlauch, aber es klappt nicht. Ich bekomme immer eine *.so Library. Wenn ich versuche, diese einzubinden, kommt die Meldung "qtlog.h": Datei oder Verzeichnis nicht gefunden.
Dabei habe ich im Hauptprojekt die Library mit
eingebunden (in der *.pro natürlich).
Was mache ich falsch?
Cheers
Don Tinelli
PS: Ich habe Qt 4.2 auf openSUSE 10.2
Hier mein Code:
Code: Alles auswählen
TEMPLATE = lib
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
CONFIG += dll qt thread
DEFINES += BUILD_DLL
# Input
HEADERS += qtlog.h
SOURCES += qtlog.cpp
Code: Alles auswählen
#ifndef QTLOG_H
#define QTLOG_H
#ifdef BUILD_DLL
#define EXPORT_DLL Q_DECL_EXPORT
#else
#define EXPORT_DLL
#endif
#include <QString>
#include <QTextEdit>
#include <QFile>
class QtLog : public QObject
{
Q_OBJECT
public:
QtLog(QTextEdit *txtLog, QString fileName, int mode);
void addEntry(QString entry);
bool saveToFile(QString fName);
bool saveToFile();
private:
QTextEdit *logText;
QString fileName;
int logMode;
QFile *logFile;
QString text;
};
#endif
Verfasst: 13. April 2007 19:20
von Christian81
Was hat die Library mit dem Header zu tun? Der Compiler muss schon wissen wo er nach dem Header suchen soll...
Verfasst: 13. April 2007 20:12
von lepsai
ah, jetzt verstehe ich, du wolltest auf eine Klasse aus einer festgelinkten Dll zugreifen.... hm... na ja, dann siehe oben...