Wie verwende ich eine DLL-Datei eines Drittanbieters in Visual Studio C ++?

76

Ich verstehe, dass ich LoadLibrary () verwenden muss. Aber welche anderen Schritte muss ich ausführen, um eine DLL-Datei eines Drittanbieters zu verwenden?

Ich bin einfach in C ++ gesprungen und dies ist der einzige Teil, den ich nicht bekomme (als Java-Programmierer). Ich prüfe nur, wie ich eine Qt- Bibliothek und tesseract-ocr verwenden kann, aber der Prozess macht für mich keinen Sinn und ist so schwer zu googeln.

Wie teile ich dem Compiler die von mir verwendeten Funktionen mit? Sollte es eine Include-Datei des Drittanbieters geben?

Zombies
quelle
Verstehen Sie, wie Sie in Visual Studio 2012 für C ++ DLL-Dateien von Drittanbietern hinzufügen. Bitte helfen Sie mir dabei.
Afzalex

Antworten:

72

Wie alle anderen sagen, ist LoadLibrary der schwierige Weg und kaum jemals notwendig.

Die DLL sollte eine .lib-Datei zum Verknüpfen und eine oder mehrere Header-Dateien enthalten, die # in Ihre Quellen aufgenommen werden sollen. Die Header-Dateien definieren die Klassen und Funktionsprototypen, die Sie in der DLL verwenden können. Sie benötigen dies auch, wenn Sie LoadLibrary verwenden.

Um eine Verknüpfung mit der Bibliothek herzustellen, müssen Sie möglicherweise die .lib-Datei zur Projektkonfiguration unter Linker / Eingabe / Zusätzliche Abhängigkeiten hinzufügen.

Mark Ransom
quelle
1
Danke, die anderen Antworten waren sehr gut (und auch für mich nützlich), aber dies erklärte genau, wonach ich suchte.
Zombies
Das Dialogfeld "Zusätzliche Abhängigkeiten" unterstützt anscheinend nur Dateinamen und Erweiterungen, keine Dateipfade. Durch Hinzufügen des Dateinamens + der Erweiterung wurden die Fehler "Bezeichner nicht gefunden" nicht behoben. Das Hinzufügen des vollständig qualifizierten Pfads + Dateinamens + hat sie ebenfalls nicht behoben.
anon58192932
1
@advocate, auf der Registerkarte "Allgemein" befindet sich ein Eintrag für "Zusätzliche Bibliotheksverzeichnisse". Ich habe keine Ahnung, warum Microsoft sie getrennt hat.
Mark Ransom
Ich habe das tatsächlich gemacht, aber ich bekomme immer noch Linker-Fehler. Ich habe meine DLL-Datei in mein C: / Windows gestellt. Was mache ich falsch?
Bart
1
@darkgaze können Sie verwenden, #importum automatisch eine Header-Datei für eine DLL zu generieren und einzuschließen . Der Compiler muss die Deklaration aller Funktionen kennen, damit er den aufrufenden Code erstellen kann.
Mark Ransom
67

Um DLLs von Drittanbietern in mein VS 2008 C ++ - Projekt zu integrieren, habe ich Folgendes getan (Sie sollten in der Lage sein, in 2010, 2012 usw. Zu übersetzen) ...

Ich habe die Header-Dateien zusammen mit meinen anderen Header-Dateien in meine Lösung eingefügt und Änderungen an meinem Code vorgenommen, um die Funktionen der DLLs aufzurufen (andernfalls, warum sollten wir das alles tun?). : ^) Dann habe ich den Build geändert, um den LIB-Code in meine EXE-Datei zu verknüpfen, die DLLs an ihren Platz zu kopieren und sie zu bereinigen, wenn ich eine 'Bereinigung' durchgeführt habe - ich erkläre diese Änderungen unten.

Angenommen, Sie haben zwei DLLs von Drittanbietern, A.DLL und B.DLL, und Sie haben jeweils eine Stub-LIB-Datei (A.LIB und B.LIB) und Header-Dateien (AH und BH).

  • Erstellen Sie ein "lib" -Verzeichnis unter Ihrem Lösungsverzeichnis, z. B. mit Windows Explorer.
  • Kopieren Sie Ihre .LIB- und .DLL-Dateien von Drittanbietern in dieses Verzeichnis

(Sie müssen die nächsten Änderungen einmal für jedes von Ihnen verwendete Quell-Build-Ziel vornehmen (Debug, Release).)

  1. Machen Sie Ihre EXE von den LIB-Dateien abhängig

    • Gehen Sie zu Konfigurationseigenschaften -> Linker -> Eingabe -> Zusätzliche Abhängigkeiten und listen Sie dort Ihre .LIB-Dateien einzeln auf, getrennt durch Leerzeichen : A.LIB B.LIB
    • Gehen Sie zu Konfigurationseigenschaften -> Allgemein -> Zusätzliche Bibliotheksverzeichnisse und fügen Sie Ihr "lib" -Verzeichnis zu allen bereits vorhandenen hinzu. Einträge werden durch Semikolons getrennt . Wenn Sie beispielsweise bereits $(SolutionDir)fodderdort waren, ändern Sie es $(SolutionDir)fodder;$(SolutionDir)libin "lib".
  2. Erzwingen Sie, dass die DLLs in das Ausgabeverzeichnis kopiert werden

    • Gehen Sie zu Konfigurationseigenschaften -> Build-Ereignisse -> Post-Build-Ereignis
    • Geben Sie Folgendes für die Befehlszeile ein (die Schalterbedeutungen finden Sie unter "XCOPY /?" In einem DOS-Fenster):

    XCOPY "$(SolutionDir)"\lib\*.DLL "$(TargetDir)" /D /K /Y

    • Sie können so etwas für Beschreibung eingeben:

    Copy DLLs to Target Directory

    • Vom Build ausgeschlossen sollte sein No. Klicken Sie auf OK.
  3. Weisen Sie VS an, die DLLs zu bereinigen, wenn ein Ausgabeordner bereinigt wird:

    • Gehen Sie zu Konfigurationseigenschaften -> Allgemein -> Beim Löschen zu löschende Erweiterungen und klicken Sie auf "...". Fügen Sie *.dllam Ende der Liste hinzu und klicken Sie auf OK.
reich p
quelle
2
Ich versuche, Ihre Methode zu verwenden, um DLLs von Drittanbietern zu verwenden. Ich bin mit Visual Studio 2012 Ultimate und es muß nicht Additional Library Directoriesin Configuration Properties -> GeneralTab. Bitte hilf mir.
Afzalex
6
Das sollte sein Configuration Properties -> Linker -> General -> Additional Library Directories.
Colin Robertson
@afzalex finden Sie unter Konfigurationseigenschaften> VC ++ - Verzeichnisse> Bibliotheksverzeichnisse. Es ist ein Generationswechsel;)
Bokhari
Ein Zitat wird für Schritt 2 XCOPY "$(SolutionDir)\lib\*.DLL" "$(TargetDir)" /D /K /Y
falsch
@TristanCHARBONNIER Interessant. Ich bin mir ziemlich sicher, dass ich meinen XCOPYBefehl aus meiner Arbeitskonfiguration kopiert / eingefügt habe . Wollen Sie damit sagen, dass das Zitat falsch platziert ist, weil es bei Ihnen nicht funktioniert hat, oder ist das nur Spekulation?
Rich p
24

Dies sind zwei Möglichkeiten, eine DLL-Datei in Windows zu verwenden:

  1. Es gibt eine Stub-Bibliothek (.lib) mit zugehörigen Header-Dateien. Wenn Sie Ihre ausführbare Datei mit der lib-Datei verknüpfen, wird die DLL-Datei beim Starten des Programms automatisch geladen.

  2. Manuelles Laden der DLL. Dies ist normalerweise das, was Sie tun möchten, wenn Sie ein Plugin-System entwickeln, in dem viele DLL-Dateien eine gemeinsame Schnittstelle implementieren. Weitere Informationen hierzu finden Sie in der Dokumentation zu LoadLibrary und GetProcAddress .

Für Qt würde ich vermuten, dass Header und eine statische Bibliothek verfügbar sind, die Sie in Ihr Projekt aufnehmen und verknüpfen können.

Laserallan
quelle
Und es gibt einen dritten Weg, ähnlich wie bei Ihrem ersten, mit dem /MTSchalter, der Ihre Bibliotheken statisch verknüpft. Der Vorteil ist, dass kein dynamischer Verbindungsaufwand entsteht . Dies kann jedoch nicht verwendet werden, wenn Sie auch den /clrSchalter verwenden.
Abel
2
Das gilt nur für die Standardbibliothek. Für benutzerdefinierte Bibliotheken (Drittanbieter) können Sie eine DLL nur dann statisch verknüpfen, wenn jemand explizit eine statische Version davon erstellt hat, die Sie verknüpfen können.
Laserallan
@Laserallan Ich entwickle ein DLL-Projekt, aber wenn ich es erstelle, werden nur die dllund lib-Dateien erstellt. Es wird kein includesVerzeichnis erstellt. Wie kann ich meine Header-Dateien in das Projekt aufnehmen?
Mrid
Die DLL / Import-Bibliothek sind die Ausgaben des Linkers. Wenn Sie die Includes bereitstellen möchten, müssen Sie sicherstellen, dass alles zusammen verteilt wird. Wie Sie dies tun, hängt von Ihrem Build-System ab. Wenn Sie jedoch cmake verwenden, sehen Sie sich die Befehlsfamilie install an, mit deren Hilfe Sie die wichtigen Dateien für die strukturierte Verteilung
festlegen
6

Um Qt mit dynamischer zu verwenden Verknüpfung müssen Sie die angeben libDateien ( in der Regel qtmaind.lib, QtCored4.libund QtGuid4.libfür die „Debug“ configration) in
Properties » Linker » Input » Additional Dependencies.

Sie müssen auch den Pfad angeben, in dem sich die Bibliotheken befinden , nämlich in
Properties » Linker » General » Additional Library Directories.

Und Sie müssen sicherstellen, dass die entsprechenden .dlls zur Laufzeit verfügbar sind, indem Sie sie entweder im selben Ordner wie Ihr .exeoder in einem Ordner auf Ihrem Pfad speichern .

drby
quelle
3

Sie müssen LoadLibrary nur verwenden, wenn Sie spät binden und die importierten Funktionen nur zur Laufzeit auflösen möchten. Der einfachste Weg, eine DLL eines Drittanbieters zu verwenden, besteht darin, eine Verknüpfung mit einer .lib herzustellen.


Als Antwort auf Ihre Bearbeitung:

Ja, die Drittanbieter-API sollte aus einer DLL und / oder einer Bibliothek bestehen, die die Implementierungs- und Header-Dateien enthält, die die erforderlichen Typen deklarieren. Sie müssen die Typdefinitionen kennen, unabhängig davon, welche Methode Sie verwenden. Für LoadLibrary müssen Sie Funktionszeiger definieren, damit Sie stattdessen genauso einfach Ihre eigene Header-Datei schreiben können. Grundsätzlich müssen Sie LoadLibrary nur verwenden, wenn Sie eine späte Bindung wünschen. Ein triftiger Grund dafür wäre, wenn Sie nicht sicher sind, ob die DLL auf dem Ziel-PC verfügbar sein wird.

Stu Mackellar
quelle
2

Wenn Sie davon ausgehen können, dass Sie es verwenden können, sollte die Bibliothek eines Drittanbieters eine * .lib-Datei sowie eine * .dll-Datei enthalten. Sie müssen lediglich die * .lib zur Liste der Eingabedateien in den 'Linker'-Optionen Ihres Projekts hinzufügen.

Diese * .lib-Datei ist nicht unbedingt eine 'statische' Bibliothek (die Code enthält). Stattdessen kann eine * .lib nur eine Datei sein, die Ihre ausführbare Datei mit der DLL verknüpft.

ChrisW
quelle