Funktionen aus externer Bibliothek nutzen

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
matthiasw
Beiträge: 20
Registriert: 24. April 2014 13:50

Funktionen aus externer Bibliothek nutzen

Beitrag von matthiasw »

Hallo,

ich benutze den Qt Creator 2.4.0 und möchte innerhalb eines Projektes Funktionen eines Drittanbieters nutzen. Der Anbieter stellt dafür eine .lib, mehrere .dll (darunter eine, die genauso heißt wie die .lib) sowie mehrere Header-Dateien zur Verfügung.

Mein Ansatz war, die .lib über die Projektdatei als statische externe Bibliothek einzubinden, ich habe dafür den Wizard benutzt:

win32: LIBS += -LPfadZuExternerLib/ -lexterneLib
win32: PRE_TARGETDEPS += PfadZuExternerLib/ExterneLib.lib

Der Pfad zu den Header-Dateien wurde ebenfalls in der Projektdatei bekannt gemacht.

INCLUDEPATH += PfadZuHeaderdateien
DEPENDPATH += PfadZuHeaderdateien

Das Projekt wird auch problemlos kompiliert. Wird aber zur Laufzeit auf eine Funktion des Drittanbieters zugegriffen, kommt es zu einem Segmentation Fault und das Programm schmiert natürlich ab mit dem Fehlercode: -1073741819 (ungültiger Zugriff eines Prozesses auf einen Bereich außerhalb des ihm zugeordneten Speicherbereiches) :(

Mich wundert es, dass die Funktionen in den Headern über dllimports bekannt gemacht werden. Ist das auch bei Funktionen aus einer .lib so? Ein Beispiel:

extern "C" __declspec(dllimport) HANDLE WINAPI NameDerFunktion(...);

Nach einer .dll beim Einbinden der .lib wurde ich aber nie gefragt. Ein Einbinden der dll zur Laufzeit über die QLibrary-Klasse funktioniert scheinbar auch nicht, der Rückgabewert von isLoaded gibt immer "false" zurück.

Hat jemand eine Idee, was ich falsch mache? Vielen Dank im Voraus!

Gruß Matthias
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Funktionen aus externer Bibliothek nutzen

Beitrag von Christian81 »

Ist die Library auch für den gleichen Compiler kompiliert? Auch mit den gleichen Compilerflags (ich denke da vor allem an /MD(d) bzw. /MT(d)) und hat die externe Lib alle nötigen Dependencies vorliegen -> DependencyWalker ? An Qt liegt das definitiv nicht - das kannst Du recht schnell herausfinden indem Du einfache eine kleine main.cpp baust die nur eine Funktion der externen Lib aufruft.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
matthiasw
Beiträge: 20
Registriert: 24. April 2014 13:50

Re: Funktionen aus externer Bibliothek nutzen

Beitrag von matthiasw »

Hallo Christian,

scheinbar ist die .lib für den VC++ gebaut. Der Drittanbieter gibt zu den Bibliotheken Beispielprojekte mit, die beim Debuggen im Visual Studio nicht zu einem Segmentation Fault führen, wenn auf eine externe Funktion zugegriffen wird.

Kann ich mir mit den Qt-Tools bzw. wohl eher mit den mingw-Tools selber aus der gleichnahmigen .dll eine .lib bauen? Wenn ja, wie? :)

Die gleichnahmige .dll habe ich übrigens nach den Funktionen durchsucht und sie sind alle in dieser .dll vorhanden.

Gruß Matthias
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Funktionen aus externer Bibliothek nutzen

Beitrag von Christian81 »

Der gcc/mingw kann normalerweise gegen C-Funktionen, welche mit VisualStudio gebaut wurden, linken ohne dass es Probleme gibt. Sind C++ Funktionen/Klassen mit im Spiel wird es nix.
Wenn der Linker ordentlich durchläuft sehe ich keinen Grund eine Export-Lib noch einmal selbst von Hand zu bauen. Ich würde das machen was ich schon vorgeschlagen habe...
Außerdem verschiebe ich es mal - das hat nix mit Qt zu tun :)
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
matthiasw
Beiträge: 20
Registriert: 24. April 2014 13:50

Re: Funktionen aus externer Bibliothek nutzen

Beitrag von matthiasw »

Nach einiger Recherche habe ich auf der MinGW-Seite Informationen gefunden, womit eine MSVC-kompilierte dll mit einem unter MinGW kompilierten Programm zusammen arbeiten sollte.

http://www.mingw.org/wiki/MSVC_and_MinGW_DLLs

Ich habe mir mit Hilfe von pexports und dlltool jetzt eine .a Bibliothek gebaut und eingebunden. Nun kommt aber die folgende Fehlermeldung:

undefined reference to `_imp__NameDerFunktion@12'

Die Tools haben scheinbar die Symbole mit Pre- und Postfixes versehen. Wie rufe ich diese jetzt im Programm auf? Muss die Header-Datei, die die Funktionen bekannt macht, abgeändert werden? Zu dem @12 hinten dran hatte ich schon mal was gefunden, was wieder mit dem MSVC-Compiler zu tun hatte.

Da die Funktionen alle mit extern "C" bekannt gemacht werden, gehe ich davon aus, das es sich um reine C-Funktionen handelt.

Gruß Matthias
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Funktionen aus externer Bibliothek nutzen

Beitrag von Christian81 »

Nochmal: Wenn es linkt musst Du keine .a - Datei (was auch nur eine Import-Lib mit einer anderen Endung ist) bauen!
Wenn es beim Starten crasht dann bau, wie oben geschrieben, eine einfache main mit einem Aufruf zur Funktion aus der Dll. Wenn es dann crasht müssen irgendwelche Compileroptionen (siehe oben ...) nicht korrekt sein was bei dem Optionendschungel von msvc leicht passieren kann.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
matthiasw
Beiträge: 20
Registriert: 24. April 2014 13:50

Re: Funktionen aus externer Bibliothek nutzen

Beitrag von matthiasw »

Das Problem ist gelöst :)

Wie du schon geschrieben hast, die .lib war in Ordnung. Danke für deine Hilfe! Der Fehler beim Aufruf der externen Funktionen lag an dessen Parametern. Die Funktionen erwarten Zeichenketten vom Typ LPCTSTR, diese können beim MSVC direkt mit

LPCTSTR var = "Zeichenkette";

angelegt und der Funktion übergeben werden. Beim MinGW musste ich den Umweg gehen über:

TCHAR var[] = "Zeichenkette";
LPCTSTR pvar = var;

Den Zeiger pvar nimmt die Funktion dann an ohne abzuschmieren. Gibt es einen Compiler-Schalter für den MinGW, der das Verhalten vom MSVC nachbildet?

Zudem musste ich in der Projektdatei den define für UNICODE entfernen, damit er nicht bei jedem TCHAR oder WCHAR rummeckert. Eine Sache habe ich noch, und zwar bekomme ich noch die Fehlermeldung:

parameter 'blabla' includes pointer to array of unknown bound 'TCHAR [][32]'

Das Problem ist nichts schwerwiegendes, da dieser Fehler nur bei einer nicht benötigten Funktion auftritt und ich diese einfach im Header auskommentieren kann. Die Fehlermeldung tritt im MSVC nicht auf. Das kann doch bestimmt auch mit einem Compiler-Schalter erledigt werden, oder? :)

Gruß Matthias
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Funktionen aus externer Bibliothek nutzen

Beitrag von Christian81 »

Das mit UNICODE oder nicht hätte in der Dokumentation zu der externen Lib drinstehen müssen da sie ja den Typ TCHAR (bzw. LP(C)TSTR) benutzen. Dieser ist je nachdem ob UNICODE definiert ist oder nicht entweder ein char oder ein wchar. Und sie haben die Library gebaut und UNICODE war nicht gesetzt.

Ich würde um das include der externen Library ein

Code: Alles auswählen

#ifdef UNICODE
#define NEED_UNICODE 1
#undef UNICODE
#endif
// die externe Library ist ohne UNICODEgebaut worden, also char, LPSTR/LPCSTR
#include <blub.h>
#ifdef NEED_UNICODE
#define UNICODE
#endif
setzen. Dann ist Ruhe.
TCHAR [][32] ist demach wie 'char [][32]' zu lesen was eine nicht definierte Anzahl an Zeigern auf Zeichenketten mit maximal 31 Zeichen sein soll. Dies ist aber kein korrekter C - Konstrukt und nur eine nicht standardkonforme MSVC-Erweiterung. Im Grunde ist 'char **' das Gleiche da die Zeichenkettenbeschränkung vom Compiler eh nicht überprüft wird. Aber wenn du die Funktion nicht benötigst dann lass sie auskommentiert.

Hier nochmal was zum Nachlesen: http://stackoverflow.com/questions/3214 ... and-lptstr
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Antworten