Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In dieser schrittweisen exemplarischen Vorgehensweise wird erläutert, wie Sie die Visual Studio-IDE verwenden, um ihre eigene dll (Dynamic Link Library) zu erstellen, die in Microsoft C++ (MSVC) geschrieben wurde, und wie Sie die DLL aus einer anderen C++-App verwenden. DLLs, auch als freigegebene Bibliotheken in UNIX-basierten Betriebssystemen bezeichnet, sind eine der nützlichsten Arten von Windows-Komponenten. Sie können sie verwenden, um Code und Ressourcen zu teilen und die Größe Ihrer Apps zu verkleinern. DLLs können sogar die Wartung und Erweiterung Ihrer Apps vereinfachen.
In dieser exemplarischen Vorgehensweise erstellen Sie eine DLL, die einige mathematische Funktionen implementiert. Anschließend erstellen Sie eine Konsolen-App, die die Funktionen aus der DLL verwendet. Außerdem erhalten Sie eine Einführung in einige der Programmiertechniken und Konventionen, die in Windows-DLLs verwendet werden.
In dieser Anleitung werden die folgenden Schritte abgedeckt:
- Erstellen Sie ein DLL-Projekt in Visual Studio.
- Fügen Sie der DLL exportierte Funktionen und Variablen hinzu.
- Erstellen Sie ein Konsolen-App-Projekt in Visual Studio.
- Verwenden Sie die Funktionen und Variablen, die aus der DLL in der Konsolen-App importiert wurden.
- Führen Sie die fertige App aus.
Wie eine statisch verknüpfte Bibliothek exportiert eine DLL Variablen, Funktionen und Ressourcen anhand des Namens. Eine Client-App importiert die Namen, um diese Variablen, Funktionen und Ressourcen zu verwenden. Im Gegensatz zu einer statisch verknüpften Bibliothek verbindet Windows die Importe in Ihrer App mit den Exporten in einer DLL zur Ladezeit oder zur Laufzeit, anstatt sie zur Linkzeit zu verbinden. Windows erfordert zusätzliche Informationen, die nicht Teil des C++-Standardkompilierungsmodells sind, um diese Verbindungen herzustellen. Der MSVC-Compiler implementiert einige microsoftspezifische Erweiterungen für C++, um diese zusätzlichen Informationen bereitzustellen. Wir erklären diese Erweiterungen im Verlauf.
Diese exemplarische Vorgehensweise erstellt zwei Visual Studio-Lösungen: eine, die die DLL erstellt und eine, die die Client-App erstellt. Die DLL verwendet die C-Aufrufkonvention. Es kann von Apps aufgerufen werden, die in anderen Programmiersprachen geschrieben wurden, solange die Plattform, aufrufkonventionen und Verknüpfungskonventionen übereinstimmen. Die Client-App verwendet implizite Verknüpfungen, wobei Windows die App zur Ladezeit mit der DLL verknüpft. Mit dieser Verknüpfung kann die App die von der DLL bereitgestellten Funktionen genau wie die Funktionen in einer statisch verknüpften Bibliothek aufrufen.
Diese Anleitung behandelt einige häufige Situationen nicht. Der Code zeigt nicht die Verwendung von C++-DLLs durch andere Programmiersprachen an. Es wird nicht gezeigt, wie eine Ressourcen-Only-DLL erstellt wird oder wie explizite Verknüpfung verwendet wird, um DLLs zur Laufzeit anstelle zur Ladezeit zu laden. Seien Sie sicher, Sie können MSVC und Visual Studio verwenden, um all diese Dinge zu erledigen.
Obwohl der Code der DLL in C++ geschrieben wird, verwenden wir C-Style-Schnittstellen für die exportierten Funktionen. Hierfür gibt es zwei Hauptgründe: Zunächst unterstützen viele andere Sprachen Importe von C-Formatfunktionen. Die Client-App muss nicht in C++ geschrieben werden. Zweitens werden einige häufige Fallstricke im Zusammenhang mit exportierten Klassen und Memberfunktionen vermieden. Es ist einfach, beim Exportieren von Klassen schwer zu diagnostizierende Fehler zu machen, da alles, was in einer Klassendeklaration bezeichnet wird, über eine Instanziierung verfügen muss, die ebenfalls exportiert wird. Diese Einschränkung gilt für DLLs, aber keine statischen Bibliotheken. Wenn Ihre Klassen im Plain-Old-Data-Stil sind, sollten Sie auf dieses Problem nicht stoßen.
Links zu weiteren Informationen zu DLLs finden Sie unter Erstellen von C/C++-DLLs in Visual Studio. Weitere Informationen zu impliziter Verknüpfung und expliziter Verknüpfung finden Sie unter Ermitteln der zu verwendenden Verknüpfungsmethode. Informationen zum Erstellen von C++-DLLs für die Verwendung mit Programmiersprachen, die C-Sprachverknüpfungskonventionen verwenden, finden Sie unter Exportieren von C++-Funktionen für die Verwendung in ausführbaren Dateien in C-Sprache. Informationen zum Erstellen von DLLs für die Verwendung mit .NET-Sprachen finden Sie unter Aufrufen von DLL-Funktionen aus Visual Basic Applications.
Voraussetzungen
- Microsoft Windows 7 oder höher. Wir empfehlen die neueste Version von Windows für eine optimale Entwicklungsumgebung.
Visual Studio. Informationen zum Herunterladen und Installieren von Visual Studio finden Sie unter Installieren von Visual Studio. Stellen Sie beim Ausführen des Installers sicher, dass die Desktopentwicklung mit C++ -Workload überprüft ist. Machen Sie sich keine Sorgen, wenn Sie diese Workload nicht installiert haben, wenn Sie Visual Studio installiert haben. Sie können das Installationsprogramm erneut ausführen und es jetzt installieren.
- Visual Studio. Informationen zum Herunterladen und Installieren von Visual Studio 2015 finden Sie unter Installieren von Visual Studio 2015. Verwenden Sie eine benutzerdefinierte Installation, um den C++-Compiler und die C++-Tools zu installieren, da sie nicht standardmäßig installiert sind.
Ein Verständnis der Grundlagen der Verwendung der Visual Studio-IDE. Wenn Sie zuvor Windows-Desktop-Apps verwendet haben, können Sie wahrscheinlich auf dem Laufenden bleiben. Eine Einführung finden Sie in der Visual Studio IDE-Featuretour.
Einige Kenntnisse in der Sprache C++. Keine Sorge, wir tun nichts zu kompliziert.
Hinweis
In dieser exemplarischen Vorgehensweise wird davon ausgegangen, dass Sie Visual Studio 2017, Version 15.9 oder höher, verwenden. Einige frühere Versionen von Visual Studio 2017 hatten Fehler in den Codevorlagen oder verwendeten verschiedene Dialogfelder für die Benutzeroberfläche. Um Probleme zu vermeiden, verwenden Sie visual Studio Installer, um Visual Studio 2017 auf Version 15.9 oder höher zu aktualisieren.
Erstellen des DLL-Projekts
In den folgenden Aufgabengruppen erstellen Sie ein Projekt für Ihre DLL, fügen Code hinzu und erstellen es. Starten Sie zunächst die Visual Studio-IDE, und melden Sie sich bei Bedarf an. Die Anweisungen variieren geringfügig, je nachdem, welche Version von Visual Studio Sie verwenden. Um die Schritte für Ihre bevorzugte Version von Visual Studio anzuzeigen, verwenden Sie die Versionsauswahl oben im Inhaltsverzeichnis auf dieser Seite.
So erstellen Sie ein DLL-Projekt in Visual Studio
Klicken Sie in der Menüleiste auf Datei>Neu>Projekt, um das Dialogfeld Neues Projekt erstellen zu öffnen.
Legen Sie oben im Dialogfeld " Sprache " auf C++ fest, legen Sie "Plattform " auf Windows fest, und legen Sie den Projekttyp auf "Library" fest.
Wählen Sie in der gefilterten Liste der Projekttypen die Option Dynamic Link Library (DLL) und dann "Weiter" aus.
Geben Sie auf der Seite " Neues Projekt konfigurieren " "MathLibrary " in das Feld "Projektname " ein, um einen Namen für das Projekt anzugeben. Behalten Sie die Standardwerte "Speicherort" und "Lösungsname" bei. Legen Sie "Lösung " auf " Neue Lösung erstellen" fest. Deaktivieren Sie das Kontrollkästchen "Projektmappe und Projekt im selben Verzeichnis platzieren", wenn es aktiviert ist.
Klicken Sie auf die Schaltfläche Erstellen, um das Projekt zu erstellen.
Wenn die Projektmappe erstellt wird, können Sie die generierten Projekt- und Quelldateien im Projektmappen-Explorer-Fenster in Visual Studio anzeigen.
So erstellen Sie ein DLL-Projekt in Visual Studio 2017
Klicken Sie in der Menüleiste auf Datei>Neu>Projekt, um das Dialogfeld Neues Projekt zu öffnen.
Wählen Sie im linken Bereich des Dialogfelds "Neues Projekt" die Option "Visual>> installiert" aus. Wählen Sie im mittleren Bereich Dynamic-Link Bibliothek (DLL) aus. Geben Sie MathLibrary in das Feld "Name " ein, um einen Namen für das Projekt anzugeben. Behalten Sie die Standardwerte Speicherort und Lösungsname bei. Legen Sie "Lösung " auf " Neue Lösung erstellen" fest. Überprüfen Sie Verzeichnis für die Lösung erstellen, wenn es nicht aktiviert ist.
Wählen Sie die Schaltfläche "OK " aus, um das Projekt zu erstellen.
Nach dem Erstellen der Projektmappe können Sie die generierten Projekt- und Quelldateien im Projektmappen-Explorer in Visual Studio anzeigen.
So erstellen Sie ein DLL-Projekt in Visual Studio 2015 und älteren Versionen
Klicken Sie in der Menüleiste auf Datei>Neu>Projekt.
Erweitern Sie im linken Bereich des Dialogfelds "Neues Projekt" die Option "Installierte>Vorlagen", und wählen Sie "Visual C++" aus, und wählen Sie dann im mittleren Bereich "Win32-Konsolenanwendung" aus. Geben Sie MathLibrary in das Bearbeitungsfeld "Name " ein, um einen Namen für das Projekt anzugeben. Behalten Sie die Standardwerte Speicherort und Lösungsname bei. Legen Sie "Lösung " auf " Neue Lösung erstellen" fest. Wenn Verzeichnis für Lösung erstellen nicht aktiviert ist, aktivieren Sie es.
Klicken Sie auf die Schaltfläche "OK ", um das Dialogfeld " Neues Projekt " zu schließen und den Win32-Anwendungs-Assistenten zu starten.
Klicken Sie auf Weiter. Wählen Sie auf der Seite "Anwendungseinstellungen" unter "Anwendungstyp"DLL aus.
Wählen Sie die Schaltfläche "Fertig stellen " aus, um das Projekt zu erstellen.
Wenn der Assistent die Lösung abgeschlossen hat, können Sie die generierten Projekt- und Quelldateien im Projektmappen-Explorer-Fenster in Visual Studio sehen.
Gerade jetzt tut diese DLL nicht sehr viel. Als Nächstes erstellen Sie eine Headerdatei, um die Funktionen zu deklarieren, die Ihre DLL-Exporte ausführen, und fügen Sie dann die Funktionsdefinitionen der DLL hinzu, um sie nützlicher zu machen.
So fügen Sie der DLL eine Headerdatei hinzu
Um eine Headerdatei für Ihre Funktionen zu erstellen, wählen Sie auf der Menüleiste "Projekt>Neues Element hinzufügen" aus.
Wählen Sie im Dialogfeld " Neues Element hinzufügen " im linken Bereich visual C++ aus. Wählen Sie im mittleren Bereich Header-Datei (.h) aus. Geben Sie als Namen für die Headerdatei an
MathLibrary.h.
Wählen Sie die Schaltfläche "Hinzufügen " aus, um eine leere Kopfzeilendatei zu generieren, die in einem neuen Editorfenster angezeigt wird.
Ersetzen Sie den Inhalt der Headerdatei durch diesen Code:
// MathLibrary.h - Contains declarations of math functions #pragma once #ifdef MATHLIBRARY_EXPORTS #define MATHLIBRARY_API __declspec(dllexport) #else #define MATHLIBRARY_API __declspec(dllimport) #endif // The Fibonacci recurrence relation describes a sequence F // where F(n) is { n = 0, a // { n = 1, b // { n > 1, F(n-2) + F(n-1) // for some initial integral values a and b. // If the sequence is initialized F(0) = 1, F(1) = 1, // then this relation produces the well-known Fibonacci // sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, ... // Initialize a Fibonacci relation sequence // such that F(0) = a, F(1) = b. // This function must be called before any other function. extern "C" MATHLIBRARY_API void fibonacci_init( const unsigned long long a, const unsigned long long b); // Produce the next value in the sequence. // Returns true on success and updates current value and index; // false on overflow, leaves current value and index unchanged. extern "C" MATHLIBRARY_API bool fibonacci_next(); // Get the current value in the sequence. extern "C" MATHLIBRARY_API unsigned long long fibonacci_current(); // Get the position of the current value in the sequence. extern "C" MATHLIBRARY_API unsigned fibonacci_index();
Diese Headerdatei deklariert einige Funktionen, um eine generalisierte Fibonacci-Sequenz mit zwei Anfangswerten zu erzeugen. Ein Aufruf von fibonacci_init(1, 1) erzeugt die vertraute Fibonacci-Zahlenfolge.
Beachten Sie die Präprozessoranweisungen oben in der Datei. Die neue Projektvorlage für ein DLL-Projekt fügt <PROJECTNAME>_EXPORTS den definierten Präprozessormakros hinzu. In diesem Beispiel definiert MATHLIBRARY_EXPORTS Visual Studio, wann Ihr MathLibrary DLL-Projekt erstellt wird.
Wenn das MATHLIBRARY_EXPORTS Makro definiert ist, legt das MATHLIBRARY_API Makro den __declspec(dllexport) Modifizierer für die Funktionsdeklarationen fest. Dieser Modifizierer weist den Compiler und Linker an, eine Funktion oder Variable aus der DLL für die Verwendung durch andere Anwendungen zu exportieren. Wenn MATHLIBRARY_EXPORTS undefiniert ist, zum Beispiel, wenn die Headerdatei von einer Clientanwendung eingeschlossen wird, wird MATHLIBRARY_API der __declspec(dllimport) Modifizierer auf die Deklarationen angewendet. Dieser Modifizierer optimiert den Import der Funktion oder Variable in einer Anwendung. Weitere Informationen finden Sie unter dllexport, dllimport.
So fügen Sie der DLL eine Implementierung hinzu
Klicken Sie im
Projektmappen-Explorer mit der rechten Maustaste auf das Verzeichnis "Quelldateien " und wählen SieHinzufügen Neues Element " aus. Erstellen Sie eine neue .cppDatei namensMathLibrary.cpp" auf die gleiche Weise, wie Sie im vorherigen Schritt eine neue Headerdatei hinzugefügt haben.Wählen Sie im Editorfenster die
MathLibrary.cppRegisterkarte aus, wenn sie bereits geöffnet ist. Wenn nicht, doppelklicken Sie im Projektmappen-Explorer aufMathLibrary.cppden Ordner " Quelldateien " des MathLibrary-Projekts , um es zu öffnen.Ersetzen Sie im Editor den Inhalt der
MathLibrary.cppDatei durch den folgenden Code:// MathLibrary.cpp : Defines the exported functions for the DLL. #include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier #include <utility> #include <limits.h> #include "MathLibrary.h" // DLL internal state variables: static unsigned long long previous_; // Previous value, if any static unsigned long long current_; // Current sequence value static unsigned index_; // Current seq. position // Initialize a Fibonacci relation sequence // such that F(0) = a, F(1) = b. // This function must be called before any other function. void fibonacci_init( const unsigned long long a, const unsigned long long b) { index_ = 0; current_ = a; previous_ = b; // see special case when initialized } // Produce the next value in the sequence. // Returns true on success, false on overflow. bool fibonacci_next() { // check to see if we'd overflow result or position if ((ULLONG_MAX - previous_ < current_) || (UINT_MAX == index_)) { return false; } // Special case when index == 0, just return b value if (index_ > 0) { // otherwise, calculate next sequence value previous_ += current_; } std::swap(current_, previous_); ++index_; return true; } // Get the current value in the sequence. unsigned long long fibonacci_current() { return current_; } // Get the current index position in the sequence. unsigned fibonacci_index() { return index_; }
Wählen Sie im Editorfenster die Registerkarte für MathLibrary.cpp aus, wenn sie bereits geöffnet ist. Wenn nicht, doppelklicken Sie im Projektmappen-Explorer im Ordner "Quelldateien" des MathLibrary-Projekts auf MathLibrary.cpp, um es zu öffnen.
Ersetzen Sie im Editor den Inhalt der
MathLibrary.cppDatei durch den folgenden Code:// MathLibrary.cpp : Defines the exported functions for the DLL. #include "stdafx.h" // use pch.h in Visual Studio 2019 and later #include <utility> #include <limits.h> #include "MathLibrary.h" // DLL internal state variables: static unsigned long long previous_; // Previous value, if any static unsigned long long current_; // Current sequence value static unsigned index_; // Current seq. position // Initialize a Fibonacci relation sequence // such that F(0) = a, F(1) = b. // This function must be called before any other function. void fibonacci_init( const unsigned long long a, const unsigned long long b) { index_ = 0; current_ = a; previous_ = b; // see special case when initialized } // Produce the next value in the sequence. // Returns true on success, false on overflow. bool fibonacci_next() { // check to see if we'd overflow result or position if ((ULLONG_MAX - previous_ < current_) || (UINT_MAX == index_)) { return false; } // Special case when index == 0, just return b value if (index_ > 0) { // otherwise, calculate next sequence value previous_ += current_; } std::swap(current_, previous_); ++index_; return true; } // Get the current value in the sequence. unsigned long long fibonacci_current() { return current_; } // Get the current index position in the sequence. unsigned fibonacci_index() { return index_; }
Um zu überprüfen, ob alles bisher funktioniert, kompilieren Sie die DLL. Wählen Sie zum Kompilieren in der Menüleiste Bereitstellen>Lösung erstellen aus. Die DLL und die zugehörige Compilerausgabe werden in einem Ordner Debug direkt unterhalb des Lösungsordners platziert. Wenn Sie einen Release-Build erstellen, wird die Ausgabe in einem Ordner mit dem Namen "Release" platziert. Die Ausgabe sollte in etwa so aussehen:
1>------ Build started: Project: MathLibrary, Configuration: Debug Win32 ------
1>pch.cpp
1>dllmain.cpp
1>MathLibrary.cpp
1>Generating Code...
1> Creating library C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.lib and object C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.exp
1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
1>------ Build started: Project: MathLibrary, Configuration: Debug Win32 ------
1>stdafx.cpp
1>dllmain.cpp
1>MathLibrary.cpp
1>Generating Code...
1> Creating library C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.lib and object C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.exp
1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
1>------ Build started: Project: MathLibrary, Configuration: Debug Win32 ------
1>MathLibrary.cpp
1>dllmain.cpp
1>Generating Code...
1> Creating library C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.lib and object C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.exp
1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.dll
1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.pdb (Partial PDB)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Herzlichen Glückwunsch, Sie haben eine DLL mit Visual Studio erstellt! Als Nächstes erstellen Sie eine Client-App, die die von der DLL exportierten Funktionen verwendet.
Erstellen einer Client-App, die die DLL verwendet
Wenn Sie eine DLL erstellen, überlegen Sie, wie Client-Apps sie verwenden könnten. Um die Funktionen aufzurufen oder auf die von einer DLL exportierten Daten zuzugreifen, muss Clientquellcode die Deklarationen zur Kompilierungszeit zur Verfügung haben. Zur Linkzeit benötigt der Linker Informationen, um die Funktionsaufrufe oder Datenzugriffe aufzulösen. Eine DLL stellt diese Informationen in einer Importbibliothek bereit, eine Datei, die Informationen zum Auffinden der Funktionen und Daten enthält, anstelle des tatsächlichen Codes. Und zur Laufzeit muss die DLL für den Client verfügbar sein, an einem Speicherort, den das Betriebssystem finden kann.
Unabhängig davon, ob es sich um Ihren eigenen oder von einem Drittanbieter handelt, benötigt Ihr Client-App-Projekt mehrere Informationen, um eine DLL zu verwenden. Sie muss die Header finden, die die DLL-Exporte deklarieren, die Importbibliotheken für den Linker und die DLL selbst. Eine Lösung besteht darin, alle diese Dateien in Ihr Clientprojekt zu kopieren. Bei DLLs von Drittanbietern, die sich während der Entwicklung Ihres Clients wahrscheinlich nicht ändern, könnte diese Methode die beste Methode sein, um sie zu verwenden. Wenn Sie jedoch auch die DLL erstellen, ist es besser, Duplizierungen zu vermeiden. Wenn Sie eine lokale Kopie von DLL-Dateien erstellen, die entwickelt werden, ändern Sie möglicherweise versehentlich eine Headerdatei in einer Kopie, aber nicht in der anderen, oder verwenden Sie eine veraltete Bibliothek.
Um asynchronen Code zu vermeiden, empfehlen wir, den Includepfad im Clientprojekt festzulegen, damit dieser die DLL-Headerdateien direkt vom DLL-Projekt einbindet. Legen Sie außerdem den Bibliothekspfad in Ihr Clientprojekt fest, um die DLL-Importbibliotheken aus dem DLL-Projekt einzuschließen. Kopieren Sie schließlich die integrierte DLL aus dem DLL-Projekt in Ihr Client-Build-Ausgabeverzeichnis. In diesem Schritt kann Ihre Client-App den gleichen DLL-Code verwenden, den Sie erstellen.
So erstellen Sie eine Client-App in Visual Studio
Wählen Sie auf der Menüleiste "Neues>Projekt>" aus, um das Dialogfeld "Neues Projekt erstellen" zu öffnen.
Legen Sie oben im Dialogfeld die Sprache auf C++, die Plattform auf Windows und den Projekttyp auf Konsole fest.
Wählen Sie aus der gefilterten Projekttypliste Konsolen-App aus, und klicken Sie auf Weiter.
Geben Sie auf der Seite " Neues Projekt konfigurieren " "MathClient " in das Feld "Projektname " ein, um einen Namen für das Projekt anzugeben. Behalten Sie die Standardwerte Speicherort und Lösungsname bei. Legen Sie "Lösung " auf " Neue Lösung erstellen" fest. Deaktivieren Sie das Kontrollkästchen "Projektmappe und Projekt im selben Verzeichnis platzieren", wenn es aktiviert ist.
Klicken Sie auf die Schaltfläche Erstellen, um das Clientprojekt zu erstellen.
Es wird ein minimales Konsolenanwendungsprojekt für Sie erstellt. Der Name der Hauptquelldatei entspricht dem Projektnamen, den Sie zuvor eingegeben haben. In diesem Beispiel wird er benannt MathClient.cpp. Sie können es erstellen, aber sie verwendet ihre DLL noch nicht.
So erstellen Sie eine Client-App in Visual Studio 2017
Um eine C++-App zu erstellen, die die von Ihnen erstellte DLL verwendet, wählen Sie auf der Menüleiste "Neues>Projekt> aus.
Wählen Sie im linken Bereich des Dialogfelds "Neues Projekt" die Option "Windows Desktop" unter "Visual C++>" aus. Wählen Sie im mittleren Bereich die Windows-Konsolenanwendung aus. Geben Sie den Namen für das Projekt , MathClient, im Bearbeitungsfeld "Name " an. Behalten Sie die Standardwerte Speicherort und Lösungsname bei. Legen Sie "Lösung " auf " Neue Lösung erstellen" fest. Wenn Verzeichnis für Lösung erstellen nicht aktiviert ist, aktivieren Sie es.
Wählen Sie "OK" aus, um das Client-App-Projekt zu erstellen.
Es wird ein minimales Konsolenanwendungsprojekt für Sie erstellt. Der Name der Hauptquelldatei entspricht dem Projektnamen, den Sie zuvor eingegeben haben. In diesem Beispiel wird er benannt MathClient.cpp. Sie können es erstellen, aber sie verwendet ihre DLL noch nicht.
So erstellen Sie eine Client-App in Visual Studio 2015
Um eine C++-App zu erstellen, die die von Ihnen erstellte DLL verwendet, wählen Sie auf der Menüleiste "Neues>Projekt> aus.
Wählen Sie im linken Bereich des Dialogfelds "Neues Projekt" unter "Installierte>>" "Win32" aus. Wählen Sie im mittleren Bereich "Win32-Konsolenanwendung" aus. Geben Sie den Namen für das Projekt , MathClient, im Bearbeitungsfeld "Name " an. Behalten Sie die Standardwerte Speicherort und Lösungsname bei. Legen Sie "Lösung " auf " Neue Lösung erstellen" fest. Wenn Verzeichnis für Lösung erstellen nicht aktiviert ist, aktivieren Sie es.
Klicken Sie auf die Schaltfläche "OK ", um das Dialogfeld " Neues Projekt " zu schließen und den Win32-Anwendungs-Assistenten zu starten. Wählen Sie auf der Seite "Übersicht " des Dialogfelds " Win32-Anwendungs-Assistent " die Schaltfläche " Weiter " aus.
Wählen Sie auf der Seite "Anwendungseinstellungen" unter "Anwendungstyp" die Option "Konsolenanwendung" aus, wenn sie noch nicht ausgewählt ist.
Wählen Sie die Schaltfläche "Fertig stellen " aus, um das Projekt zu erstellen.
Nach Abschluss des Assistenten wird ein minimales Konsolenanwendungsprojekt für Sie erstellt. Der Name der Hauptquelldatei entspricht dem Projektnamen, den Sie zuvor eingegeben haben. In diesem Beispiel wird er benannt MathClient.cpp. Sie können es erstellen, aber sie verwendet ihre DLL noch nicht.
Als Nächstes müssen Sie die Datei MathLibrary.h in Ihr Projekt einbinden, um die MathLibrary-Funktionen in Ihrem Quellcode aufzurufen. Sie können diese Headerdatei in Ihr Client-App-Projekt kopieren und dann dem Projekt als vorhandenes Element hinzufügen. Diese Methode kann eine gute Wahl für Drittanbieterbibliotheken sein. Wenn Sie jedoch den Code für Ihre DLL und Ihren Client gleichzeitig verwenden, können die Headerdateien nicht mehr synchronisiert werden. Um dieses Problem zu vermeiden, legen Sie den Pfad " Zusätzliche Includeverzeichnisse" in Ihr Projekt fest, um den Pfad zum ursprünglichen Header einzuschließen.
So fügen Sie den DLL-Header zu Ihrem include-Pfad hinzu
Klicken Sie mit der rechten Maustaste auf den Knoten "MathClient" im Projektmappen-Explorer, um das Dialogfeld Eigenschaftenseiten zu öffnen.
Wählen Sie im Dropdownfeld "Konfiguration" die Option "Alle Konfigurationen" aus, wenn sie noch nicht ausgewählt ist.
Wählen Sie im linken Bereich konfigurationseigenschaften>C/C++>Allgemein aus.
Wählen Sie im Eigenschaftenbereich das Dropdownsteuerelement neben dem Bearbeitungsfeld "Zusätzliche Includeverzeichnisse " aus, und wählen Sie dann "Bearbeiten" aus.
Doppelklicken Sie im oberen Bereich des Dialogfelds "Zusätzliche Eingeschlossene Verzeichnisse ", um ein Bearbeitungssteuerelement zu aktivieren. Oder wählen Sie das Ordnersymbol aus, um einen neuen Eintrag zu erstellen.
Geben Sie im Bearbeitungssteuerelement den Pfad zum Speicherort der
MathLibrary.hHeaderdatei an. Sie können das Auslassungszeichen (...) auswählen, um zum richtigen Ordner zu navigieren.Sie können auch einen relativen Pfad aus Ihren Clientquelldateien in den Ordner eingeben, der die DLL-Headerdateien enthält. Wenn Sie die Anweisungen befolgt haben, um Ihr Clientprojekt in eine separate Lösung von der DLL zu versetzen, sollte der relative Pfad wie folgt aussehen:
..\..\MathLibrary\MathLibraryWenn sich Ihre DLL- und Clientprojekte in derselben Lösung befinden, kann der relative Pfad wie folgt aussehen:
..\MathLibraryWenn sich die DLL- und Clientprojekte in anderen Ordnern befinden, passen Sie den relativen Pfad an. Oder verwenden Sie die Auslassungszeichen-Schaltfläche, um nach dem Ordner zu suchen.
Nachdem Sie den Pfad zur Headerdatei im Dialogfeld "Zusätzliche Includeverzeichnisse" eingegeben haben, wählen Sie die Schaltfläche "OK" aus. Wählen Sie im Dialogfeld "Eigenschaftenseiten " die Schaltfläche "OK " aus, um Ihre Änderungen zu speichern.
Sie können die MathLibrary.h Datei jetzt einschließen und die funktionen verwenden, die sie in Ihrer Clientanwendung deklariert. Ersetzen Sie den Inhalt MathClient.cpp mithilfe dieses Codes:
// MathClient.cpp : Client app for MathLibrary DLL.
// #include "pch.h" Uncomment for Visual Studio 2017 and earlier
#include <iostream>
#include "MathLibrary.h"
int main()
{
// Initialize a Fibonacci relation sequence.
fibonacci_init(1, 1);
// Write out the sequence values until overflow.
do {
std::cout << fibonacci_index() << ": "
<< fibonacci_current() << std::endl;
} while (fibonacci_next());
// Report count of values written before overflow.
std::cout << fibonacci_index() + 1 <<
" Fibonacci sequence values fit in an " <<
"unsigned 64-bit integer." << std::endl;
}
Dieser Code kann kompiliert, aber nicht verknüpft werden. Wenn Sie die Client-App jetzt erstellen, werden in der Fehlerliste mehrere LNK2019 Fehler angezeigt. Das liegt daran, dass Ihrem Projekt einige Informationen fehlen: Sie haben noch nicht angegeben, dass Ihr Projekt von der MathLibrary.lib Bibliothek abhängig ist. Und Sie haben dem Linker nicht mitgeteilt, wie er die MathLibrary.lib Datei finden soll.
Um dieses Problem zu beheben, könnten Sie die Bibliotheksdatei direkt in Ihr Client-App-Projekt kopieren. Der Linker würde es automatisch finden und verwenden. Wenn jedoch sowohl die Bibliothek als auch die Client-App entwickelt werden, kann dies zu Änderungen in einer Kopie führen, die nicht in der anderen angezeigt werden. Um dieses Problem zu vermeiden, können Sie die Eigenschaft "Zusätzliche Abhängigkeiten" festlegen, um dem Buildsystem mitzuteilen, dass Ihr Projekt von diesem abhängt MathLibrary.lib. Außerdem können Sie einen Pfad für zusätzliche Bibliotheksverzeichnisse in Ihr Projekt festlegen, um den Pfad zur ursprünglichen Bibliothek einzuschließen, wenn Sie eine Verknüpfung herstellen.
So fügen Sie die DLL-Importbibliothek zu Ihrem Projekt hinzu
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Knoten "MathClient", und wählen Sie "Eigenschaften" aus, um das Dialogfeld "Eigenschaftenseiten" zu öffnen.
Wählen Sie im Dropdownfeld "Konfiguration" die Option "Alle Konfigurationen" aus, wenn sie noch nicht ausgewählt ist. Es stellt sicher, dass alle Eigenschaftsänderungen sowohl auf Debug- als auch auf Releasebuilds angewendet werden.
Wählen Sie im linken Bereich Konfigurationseigenschaften>, Linker> und Eingabe aus. Wählen Sie im Eigenschaftenbereich das Dropdownsteuerelement neben dem Bearbeitungsfeld "Zusätzliche Abhängigkeiten" aus, und wählen Sie dann "Bearbeiten" aus.
Fügen Sie im Dialogfeld "Zusätzliche Abhängigkeiten"
MathLibrary.libzur Liste im obersten Bearbeitungssteuerelement hinzu.
Wählen Sie 'OK ' aus, um zum Dialogfeld 'Eigenschaftenseiten ' zurückzukehren.
Wählen Sie im linken Bereich Konfigurationseigenschaften>Linker>Allgemein aus. Wählen Sie im Eigenschaftenbereich das Dropdownsteuerelement neben dem Bearbeitungsfeld "Zusätzliche Bibliotheksverzeichnisse " aus, und wählen Sie dann "Bearbeiten" aus.
Doppelklicken Sie im oberen Bereich des Dialogfelds "Zusätzliche Bibliotheksverzeichnisse ", um ein Bearbeitungssteuerelement zu aktivieren. Geben Sie im Bearbeitungssteuerelement den Pfad zum Speicherort der
MathLibrary.libDatei an. Standardmäßig befindet es sich in einem Ordner namens "Debuggen " direkt unter dem DLL-Lösungsordner. Wenn Sie einen Releasebuild erstellen, wird die Datei in einem Ordner namens "Release" platziert. Sie können das$(IntDir)Makro verwenden, damit der Linker Ihre DLL finden kann, unabhängig davon, welche Art von Build Sie erstellen. Wenn Sie die Wegbeschreibungen zum Einfügen Ihres Clientprojekts in eine separate Lösung vom DLL-Projekt befolgt haben, sollte der relative Pfad wie folgt aussehen:..\..\MathLibrary\$(IntDir)Wenn sich Ihre DLL- und Clientprojekte an anderen Speicherorten befinden, passen Sie den Pfad entsprechend an.
Nachdem Sie den Pfad zur Bibliotheksdatei im Dialogfeld "Zusätzliche Bibliotheksverzeichnisse " eingegeben haben, wählen Sie die Schaltfläche "OK " aus, um zum Dialogfeld "Eigenschaftenseiten " zurückzukehren. Wählen Sie "OK" aus, um die Eigenschaftsänderungen zu speichern.
Ihre Client-App kann jetzt erfolgreich kompiliert und verknüpft werden, verfügt aber trotzdem nicht über alles, was sie ausführen muss. Wenn das Betriebssystem Ihre App lädt, wird nach der MathLibrary-DLL gesucht. Wenn die DLL in bestimmten Systemverzeichnissen, dem Umgebungspfad oder dem lokalen App-Verzeichnis nicht gefunden werden kann, schlägt die Ladefunktion fehl. Je nach Betriebssystem wird eine Fehlermeldung wie folgt angezeigt:
Eine Möglichkeit, dieses Problem zu vermeiden, besteht darin, im Rahmen des Build-Prozesses die DLL in das Verzeichnis zu kopieren, das Ihre ausführbare Datei Ihres Clients enthält. Sie können Ihrem Projekt ein Postbuildereignis hinzufügen, um einen Befehl hinzuzufügen, der die DLL in Ihr Buildausgabeverzeichnis kopiert. Der hier angegebene Befehl kopiert die DLL nur, wenn er fehlt oder geändert wurde. Es verwendet Makros, um basierend auf Ihrer Buildkonfiguration in Debug- oder Release-Verzeichnisse zu kopieren und von dort Dateien zu kopieren.
Um die DLL in einem Nach-Build-Ereignis zu kopieren
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Knoten "MathClient", und wählen Sie "Eigenschaften" aus, um das Dialogfeld "Eigenschaftenseiten" zu öffnen.
Wählen Sie im Dropdownfeld "Konfiguration" die Option "Alle Konfigurationen" aus, wenn sie noch nicht ausgewählt ist.
Wählen Sie im linken Bereich Konfigurationseigenschaften>Build-Ereignisse>Ereignis nach dem Build aus.
Wählen Sie im Eigenschaftenbereich das Bearbeitungssteuerelement im Befehlszeilenfeld aus. Wenn Sie die Anweisungen zum Platzieren des Clientprojekts in einer separaten Lösung vom DLL-Projekt befolgt haben, geben Sie diesen Befehl ein:
xcopy /y /d "..\..\MathLibrary\$(IntDir)MathLibrary.dll" "$(OutDir)"Wenn sich Ihre DLL- und Clientprojekte in anderen Verzeichnissen befinden, ändern Sie den relativen Pfad zur DLL entsprechend.
Klicken Sie auf die Schaltfläche "OK ", um Die Änderungen an den Projekteigenschaften zu speichern.
Jetzt verfügt Ihre Client-App über alles, was sie zum Erstellen und Ausführen benötigt. Erstellen Sie die Anwendung, indem Sie auf der Menüleiste " Buildlösung>erstellen " auswählen. Das Ausgabefenster in Visual Studio sollte in Abhängigkeit von Ihrer Visual Studio-Version ungefähr wie das folgende Beispiel aufweisen:
1>------ Build started: Project: MathClient, Configuration: Debug Win32 ------
1>MathClient.cpp
1>MathClient.vcxproj -> C:\Users\username\Source\Repos\MathClient\Debug\MathClient.exe
1>1 File(s) copied
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Herzlichen Glückwunsch, Sie haben eine Anwendung erstellt, die Funktionen in Ihrer DLL aufruft. Führen Sie nun Ihre Anwendung aus, um zu sehen, was sie tut. Wählen Sie auf der Menüleiste " Debuggen>starten ohne Debuggen" aus. Visual Studio öffnet ein Befehlsfenster, in dem das Programm ausgeführt werden kann. Der letzte Teil der Ausgabe sollte wie folgt aussehen:
Drücken Sie eine beliebige Taste, um das Befehlsfenster zu schließen.
Nachdem Sie nun eine DLL und eine Clientanwendung erstellt haben, können Sie experimentieren. Versuchen Sie, Haltepunkte im Code der Client-App festzulegen, und führen Sie die App im Debugger aus. Sehen Sie, was passiert, wenn Sie einen Bibliotheksaufruf aufrufen. Fügen Sie der Bibliothek weitere Funktionen hinzu, oder schreiben Sie eine andere Client-App, die Ihre DLL verwendet.
Wenn Sie Ihre App bereitstellen, müssen Sie auch die von ihr verwendeten DLLs bereitstellen. Die einfachste Möglichkeit, die von Ihnen erstellten DLLs oder die von Drittanbietern gelieferten DLLs bereitzustellen, besteht darin, sie im selben Verzeichnis wie Ihre App abzulegen. Es wird als app-lokale Bereitstellung bezeichnet. Weitere Informationen zur Bereitstellung finden Sie unter Bereitstellung in Microsoft C++.