Seite 1 von 2

[gelöst] DLLs erstellen mit QT

Verfasst: 3. Dezember 2007 21:38
von alfonsospringer
Ich möchte gern mal eine DLL erstellen um sie mit QLibrary dann laden zu können. Den Code habe ich mir aus der doku von QLibrary zusammengebastelt:

lib.h:

Code: Alles auswählen

#ifdef Q_WS_WIN
#define MY_EXPORT __declspec(dllexport)
#else
#define MY_EXPORT
#endif

extern "C" MY_EXPORT int avg(int a, int b);

lib.cpp

Code: Alles auswählen

#include "lib.h"

extern "C" MY_EXPORT int avg(int a, int b)
{
	return (a + b) / 2;
};

lib.pro

Code: Alles auswählen

######################################################################
# Automatically generated by qmake (2.01a) Mo 3. Dez 21:29:02 2007
######################################################################

TEMPLATE = app
TARGET = 
DEPENDPATH += .
INCLUDEPATH += .
CONFIG += dll

# Input
HEADERS += lib.h
SOURCES += lib.cpp
Wenn ich das ganze kompilieren will bekomme ich folgenden Fehler:

Code: Alles auswählen

f:\Qt\4.3.2\lib/libqtmain.a(qtmain_win.o):qtmain_win.cpp:(.text+0x1f7): undefined reference to `qMain(int, char**)'
collect2: ld returned 1 exit status
mingw32-make[1]: *** [release\lib.exe] Error 1
Was ist da falsch? Wie korrigiere ich es?

Verfasst: 3. Dezember 2007 22:09
von DeepDiver
http://doc.trolltech.com/4.3/qmake-comm ... -a-library

in deinem lib.pro ist der Parameter TEMPLATE falsch gesetzt.

Gruß,

Tom

Verfasst: 4. Dezember 2007 13:52
von alfonsospringer
thx, dass hab ich übersehen. Laden klappt auch wudnerbar.

Verfasst: 7. Dezember 2007 15:46
von alfonsospringer
Jetzt nachdem das laden und aufrufen klappt möchte ich das ganze wieder mal in eine Klasse stecken. Ich hab sie dll getauft und leider klappt funktioniert sie noch nicht. In der dll (hello.dll) befndet sich lediglich eine Funktion (namens hello()), die eine QMessageBox mit einem kleinen Text erscheinen lässt. So wie es in der Doku von QLibrary steht lässt sich die auch wunderbar laden und die Messagebox erscheint. Nur mit meiner Klasse klappts halt nicht :( Kann mir wer helfen? Ich bekomme beim Kompilieren weder Fehler noch Warnungen, das Programm erscheint im Task Manager, aber die MessageBox erschient nicht

main.cpp

Code: Alles auswählen

#include "loadlib.h"

int main(int argc, char *argv[]) 
{ 
	QApplication app(argc, argv); 
	dll test();
	return app.exec(); 
};
loadlib.h

Code: Alles auswählen

#include <QApplication>
#include <QLibrary>

typedef void (*func)();

class dll
{
	public:
	dll();

	private:
	func dllfunc;
	QLibrary* rootlib;
};
loadlib.cpp

Code: Alles auswählen

#include "loadlib.h"

dll::dll()
{
	rootlib = new QLibrary("hello");
	dllfunc = (func)rootlib->resolve("hello");
	dllfunc();
};

Verfasst: 7. Dezember 2007 15:49
von Christian81
Funktionen sollten nicht per QLibrary::resolve() direkt gelinkt werden. Bei Klassen funktioniert QLibrary::resolve() überhaupt nicht.

Verfasst: 7. Dezember 2007 16:42
von alfonsospringer
Aber wie kann ich's denn machen?

Verfasst: 7. Dezember 2007 16:56
von DeepDiver

Verfasst: 7. Dezember 2007 19:58
von alfonsospringer
ich glaube nicht. Was ich möchte ist eine Klasse mit einem QLibrary Member, sowie einen Funktionszeiger, der auf eine Funktion in der QLibrary gesetzt werden kann. Das nennt man doch nicht plugin, oder?
Ich möchte lediglich diesen Code (aus der Doku von QLibrary) in eine Klasse stecken :

Code: Alles auswählen

typedef void (*MyPrototype)();
 MyPrototype myFunction =
         (MyPrototype) QLibrary::resolve("mylib", "mysymbol");
 if (myFunction)
     myFunction();

Verfasst: 7. Dezember 2007 21:53
von DeepDiver
Pack Dein Projekt doch mal in ein Zip und poste das dann mal ..

Ich glaube so kommen wir schneller an Dein Ziel ...


CU Tom

Verfasst: 7. Dezember 2007 22:24
von alfonsospringer
thx, in der .zip befinden sich 2 Ordner: lib und loadlib. Im ersten ist alles was zur dll gehört und im zweiten die Klasse mit der ich die dll laden will

Verfasst: 9. Dezember 2007 21:32
von alfonsospringer
hat denn keiner eine idee, oder ist es wirklich unmöglich ?

Verfasst: 9. Dezember 2007 21:35
von Christian81
Es ist nicht unmöglich, aber ein bischen über 'wie erstelle ich eine shared lib/dll' schlaumachen wäre schon nicht schlecht.

/edit: Ausserdem verstehe ich immer noch nicht was Du willst. Wie ich schon sagte gibt es da zwei verschiedene Ansätze.
1. Laden der Lib beim Programmstart
2. Laden der Lib zur Laufzeit (so wie Du es derzeit machst)

2. geht nur wirklich einfach wenn man C-only Funktionen benutzt oder es als Plugin einsetzt (d.h. im Grunde eine C-only - Funktion die einen Ptr auf eine schöne virtuelle Klasse zurückgibt).

Wenn nichts wichtiges dagegen spricht ist 1.) immer vorzuziehen.

Verfasst: 10. Dezember 2007 08:51
von DeepDiver
Hi Alfonso,

ich habe mir soeben Deine Code mal angeschaut.
Du solltest nachdem Aufruf des Konstruktors von QLibrary die Methode load() explizit aufrufen, und den return-Wert prüfen.
http://doc.trolltech.com/4.3/qlibrary.html#load

Für den Fehlerfall lässt sich eine Fehlermeldung mit der Methode errorString() ermitteln und ausgeben.
http://doc.trolltech.com/4.3/qlibrary.html#errorString

Wenn Du das gemacht hast, wird Dir Dein Fehler wie Schuppen von den Augen fallen. :wink:

Viel Glück,

Tom

PS: Wir sollten aber trotzdem noch einmal Deine Zielsetzung der Implementierung diskutieren - wie von Christian bereits getan.
Entweder brauchst Du ein Plugin-System oder "nur" Code, der in libs ausgelagert ist. Für beide Fälle gibt es fertige Lösungen ....

Verfasst: 10. Dezember 2007 15:13
von alfonsospringer
ich hoffe euch nicht zu enttäuschen, indem ich sage, dass es sich wirklich nur um Code handelt. Die Sache ist nämlich die, dass ich noch nicht sehr lange objektorientiert programmiere und deswegen zur Übung alles was mir über den Weg läuft in Klassen schachtele ^^

sobald ich Zeit hab werde mal tun was du vorschlägst - thx

Verfasst: 10. Dezember 2007 16:13
von alfonsospringer
Zur näheren Untersuchung würde ich mir nun gerne den Return Wert von bool QLibrary::load() in einer Datei ausgeben lassen:

Code: Alles auswählen

QFile file;
file.setFileName("ausgabe.txt");
file.open(QIODevice::WriteOnly);
QDataStream out;
out.setDevice(&file);

rootlib.setFileName("hello");
bool temp = rootlib.load();
out << (QString) temp;
file.close();
dllfunc = (func)rootlib.resolve("hello");
dllfunc();
Es gibt keine Fehlermeldung, aber es entsteht keine Datei namens ausgabe.txt ->was um Himmels willen ist hier los?