40 Stimmen

Verknüpfung mit MSVC DLL aus MinGW

Ich versuche, das LizardTech GeoExpress DSDK in meine eigene Anwendung einzubinden. Ich verwende gcc, damit wir auf verschiedenen Plattformen kompilieren können. Unter Linux und Mac funktioniert das problemlos: Sie stellen eine statische Bibliothek ( libltidsdk.a ) und Kopfzeilen und wir müssen sie nur noch verwenden.

Das Kompilieren für Windows ist nicht so einfach. Sie haben die Bibliothek mit Microsoft Visual Studio erstellt, und wir verwenden MinGW. Ich habe die MinGW-FAQ gelesen und stoße auf die folgenden Probleme. Die Bibliothek ist komplett in C++ geschrieben, daher meine erste Frage: Ist das überhaupt möglich?

Nur Verknüpfung gegen die DLL, wie bereitgestellt ergibt "undefinierte Referenz" Fehler für alle C++-Aufrufe (Konstruktoren, desctructors, Methoden, etc.).

Basierend auf dem MinGW-Wiki: http://www.mingw.org/wiki/MSVC%5Fand%5FMinGW%5FDLLs Ich sollte in der Lage sein, das Dienstprogramm reimp um eine .lib in etwas Brauchbares umzuwandeln. Ich habe alle von LizardTech zur Verfügung gestellten .lib-Dateien ausprobiert, und sie geben alle "ungültige oder beschädigte Importbibliothek" an. Ich habe sowohl Version 0.4 als auch 0.3 des reimp-Dienstprogramms ausprobiert.

Mit der zweiten Methode, die im Wiki beschrieben wird, habe ich pexport und dlltool über die Dll laufen lassen, um ein .a-Archiv zu erhalten, aber das erzeugt die gleichen undefinierten Referenzen.

Übrigens: Ich habe die Diskussion unten gelesen. Es ließ einige Unklarheit darüber, ob dies möglich ist, und angesichts der MinGW Wiki-Seite scheint es wie dies sollte machbar sein. Wenn es unmöglich ist, ist das alles, was ich wissen muss. Wenn es machbar ist, würde ich gerne wissen, wie ich das hinbekomme.

Wie zu verknüpfen VS2008 generiert .libs von G++

Danke!

31voto

Chris Becke Punkte 32199

Das können Sie nicht tun. Sie haben C++-Klassen aus ihrer DLL exportiert, anstatt C-Funktionen. Der Unterschied besteht darin, dass C++-Funktionen immer mit Namen in einer veränderten Form exportiert werden, die für eine bestimmte Version des Compilers spezifisch ist.

Ihre DLL kann nur in dieser Form von msvc verwendet werden und wird wahrscheinlich nicht einmal zwischen verschiedenen Versionen von msvc funktionieren, da Microsoft sein Mangling-Schema zuvor geändert hat.

Wenn Sie ein Druckmittel haben, müssen Sie sie dazu bringen, ihre bösen Absichten zu ändern. Andernfalls müssen Sie MSVC verwenden, um eine Shim-DLL zu schreiben, die alle Klassen importiert und sie über c-Funktionen, die Schnittstellen zurückgeben, wieder exportiert.

4voto

Chris H Punkte 6087

Ich bin casi Ich bin mir sicher, dass man C++-Bibliotheken nicht auf diese Weise compilerübergreifend verknüpfen kann. Ich habe versucht, wirklich hart, aber es war vor langer Zeit und ich erinnere mich nicht an die Details. ich denke, für C-Bibliotheken ist möglich, mit einer Menge von Hacks.

1voto

Ich dachte nur, ich füge hier meinen Senf dazu.

Wenn Sie in MSVC gegen eine DLL linken wollen, verlinken Sie gegen eine .lib, die Funktionsstubs enthält, die wiederum die entsprechende Funktion in der DLL aufrufen (eine zusätzliche Umleitung mit "__imp__", das dem gemischten Namen hinzugefügt wird). GCC macht das nicht, weil man theoretisch einfach direkt mit der DLL linken kann, wenn die Funktionen durch die Exporttabelle offengelegt werden. Sie können GCC in MinGW anweisen, direkt in der dll zu suchen, indem Sie -l verwenden. Es stimmt, dass das C++-Namensschema in einigen verschiedenen Versionen von MSVC variiert, aber nicht in allen. Sie sind in den meisten Versionen konsistent und Erweiterungen werden hinzugefügt, wenn neue Funktionen implementiert werden.

MinGW verwendet jedoch das GCC-Namensmangling-Schema, das die Suche nach externen Symbolen einschließt, so dass es die von MSVC gemangelten Namen nicht erkennt. Der Linker könnte dieses Problem leicht lösen, indem er die externen Symbole so ummangelt, dass sie mit MSVC übereinstimmen, und dann erneut prüft, ob es eine Übereinstimmung gibt. Vielleicht wird dies eines Tages implementiert werden. Ich habe dies in meiner eigenen Programmiersprache auf ähnliche Weise gelöst, aber das schließt natürlich meinen eigenen Linker ein.

Es ist durchaus möglich, GCC in MinGW eine .lib zur Verfügung zu stellen, geben Sie diese einfach auf der Kommandozeile an, so wie Sie die Quelldateien angeben; gcc -o test.cpp main.cpp external.lib Dadurch erhält der Linker die Namen, nach denen er suchen soll. MinGW ist in der Lage, auch mit MSVC-veränderten Namen umzugehen, es hat sogar seinen eigenen MSVC-Mangler/Demangler in libmangle.

0voto

Adrian McCarthy Punkte 42872

Um eine DLL unter Windows zu verwenden, verknüpfen Sie sie mit einer Importbibliothek (nicht mit der DLL selbst). Importbibliotheken haben in der Regel die Erweiterung .lib (genau wie statische Bibliotheken). Wenn Sie das Windows SDK herunterladen, erhalten Sie Importbibliotheken für alle System-DLLs.

Aus Ihrer Frage geht hervor, dass Sie möglicherweise die .dll mit der .lib verwechselt haben. Sind Sie sicher, dass reimp nicht eine DLL als Input nimmt und eine .LIB-Importbibliothek erstellt, die mit MinGW kompatibel ist?

Ich habe gerade auf Wikipedia nachgeschlagen, was MinGW ist. Laut diesem Artikel wird MinGW mit weiterverteilbaren Importbibliotheken geliefert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X