Seite 1 von 1

In DLL-Header weiteren Header einbinden [gelöst]

Verfasst: 2. Februar 2010 17:54
von Kay
Hi Leute,

ich habe mir eine Matrizenklasse geschrieben, die ich per EXPORT_DLL als Library erzeuge, um sie in mein Programm einzubinden. Soweit funktioniert das auch schon gut.
Das Problem ist aber, dass die Matrizen-Headerdatei eine Vektorklasse included. Wenn ich dann in meiner Anwendung auf die Vektoren zugreifen will (indem ich zum Beispiel auf eine Spalte der Matrix zugreife) kennt er die Definition für die Zugriffsoperatoren nicht. Das bedeutet, dass die Matrixklasse zwar in der DLL vorhanden ist, die Definition der Vektorklasse allerdings nicht.
Leider klappt es nicht, einfach vor die Vektorklasse EXPORT_DLL hinzuschreiben. Dann meckert der Compiler eine "invalid function declaration" an der Stelle an.

Hier ein kurzes Beispiel, wie die Headerdatei der Matrixklasse aussieht:
[code]
#ifndef MATRIX_H
#define MATRIX_H

#ifdef MATRIXLIB_SSE2
#define EXPORT_DLL Q_DECL_EXPORT
#else
#define EXPORT_DLL
#endif

#include "colvector.h" // Hier wird die Vektorklasse eingebunden

//...

class EXPORT_DLL Matrix
{
//...
}
[/code]

Die Vektorklasse (colvector.h) ist wie jede andere Klasse definiert:
[code]
#ifndef COLVECTOR_H
#define COLVECTOR_H

// weitere includes

class ColVector
{
//...
}
[/code]

Wie kriege ich es nun hin, dass in der Matrizenlibrary auch die Definitionen für die Vektorklasse mit hinein gelinkt werden, ohne aus beiden eine Datei zu machen (sind jeweils 1000 Zeilen Code!) und ohne 2 Libraries daraus zu machen?

Danke,
Kay

Verfasst: 2. Februar 2010 21:50
von Christian81
Wann meckert er genau? Ich schätze EXPORT_DLL ist in diesem Fall nicht definiert. Für die export/import defines macht man deshalb einen eigenen Header den man überall includiert.
btw: im else-Zweig bietet sich Q_DECL_IMPORT an

Verfasst: 3. Februar 2010 10:26
von Kay
Also bei der ursprünglichen Variante (nur Klasse Matrix mit EXPORT_DLL) meckert der Linker an jeder Stelle, wo ich Member der Vektorklasse aufrufe.

Wenn ich in der Headerdatei für die Vektorklasse auch EXPORT_DLL vor den Klassennamen schreibe, dann meckert er an der Stelle an, dass es eine "invalid function declaration" ist und alle Operatordefinitionen, die danach kommen hat er auch angemeckert.

Zumindest war das gestern so.

Jetzt habe ich bei der Projektstruktur wie oben angegeben nochmal das EXPORT_DLL vor den Klassennamen der Vektorklasse geschrieben und er compiliert und linkt anstandslos.... - Keine Ahnung warum jetzt auf einmal. Aber ok. (Rebuild?)

Das Problem ist jetzt, wenn ich das Programm starte zeigt mir der "Application Output" die Fehlernummer -1073741515 an, ohne dass das Programm wirklich startet. Liegt wohl daran, dass die DLL fehlt. Kopiere ich die DLL neben meine Exe, dann läufts.

Gibt es ne Möglichkeit, dass das Programm auch ohne das Kopieren der DLL startet. Also dass die DLL beispielsweise gleich in den Ordner neben die Exe erstellt wird? Oder dass meine Software zumindest in der Entwicklungsphase im Ordner für die DLL nachschaut? (Ohne die PATH-Variable zu ändern)

Und was bedeutet das Q_DECL_IMPORT?

Verfasst: 3. Februar 2010 10:30
von Christian81
Da ich nicht weiß welches Buildsystem Du benutzt kann ich auch nicht sagen wie man die dll automatisch in ein bestimmtes Verzeichnis kopiert.

Q_DECL_IMPORT: Eigentlich nur für MSVC-Compiler nützlich. Damit wird dem Compiler gesagt dass diese Funktion importiert wird und er kann soweit ich weiß einen indirekten Aufruf wegoptimieren der beim Aufruf der Funktion aus der DLL heraus sonst benötigt würde.
Bei GCC ist Q_DECL_IMPORT leer wenn ich mich recht errinnere

Verfasst: 3. Februar 2010 10:36
von Kay
Also mein Build-System ist der QtCreator (->MinGW) auf Windows. Dachte den Output-directory kann man in der *.pro - Datei festlegen oder so?

Da ich MinGW benutze, dürfte das Q_DECL_IMPORT ja erstmal nicht wichtig für mich sein, solange niemand meinen Quellcode mit MSVC compilieren will, oder?

Verfasst: 3. Februar 2010 10:45
von Christian81
Q_DECL_IMPORT: schaden tut es auch nichts, und msvc kann auch ohne.

pro-Datei: Benutz ich nicht ;) - ich glaube DLLDESTDIR ist das was Du suchst.

Verfasst: 3. Februar 2010 10:50
von Kay
Ok, Die Dll läuft jetzt und mittels der QMake-Anweisung "DLLDESTDIR" kann man den Ausgabepfad für die DLL in der *.pro-Datei angeben. Bsp:

[code]TEMPLATE = lib

CONFIG += dll qt thread

Debug:DLLDESTDIR = ../Software/debug
Release:DLLDESTDIR = ../Software/release[/code]


Zur Zusammenfassung nochmal die Deklaration der Matrixklasse in matrix.h:
[code]#ifndef MATRIX_H
#define MATRIX_H

#ifdef MATRIXLIB_SSE2
#define EXPORT_DLL Q_DECL_EXPORT
#else
#define EXPORT_DLL Q_DECL_IMPORT
#endif

//...
#include colvector.h //Vektorklasse einbinden

class EXPORT_DLL Matrix
{...}
#endif[/code]

Und die Deklaration der Vektorklasse in colvector.h:
[code]#ifndef COLVECTOR_H
#define COLVECTOR_H

//... includes

class EXPORT_DLL ColVector
{...}

#endif[/code]

Vielleicht hilft das ja jemandem weiter.

Ansonsten vielen Dank für die Hilfe.

Verfasst: 3. Februar 2010 10:53
von Christian81
Noch eine Anmerkung: EXPORT_DLL ist nicht wirklich gut. Wenn Du nämlich eine weitere DLL hast und diese auch EXPORT_DLL benutzt gibt es Probleme. Deshalb besser z.B. <LIBNAME>_EXPORT benutzen

Verfasst: 3. Februar 2010 11:18
von Kay
Werd ich mir merken. Spätestens wenn die Plugins dazu kommen wird das dann interessant. Danke nochmal!