Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In dit stapsgewijze overzicht wordt uitgelegd hoe u de Visual Studio IDE gebruikt om uw eigen DLL-bibliotheek (Dynamic Link Library) te maken die is geschreven in Microsoft C++ (MSVC) en hoe u het DLL-bestand gebruikt vanuit een andere C++-app. DLL's, ook wel gedeelde bibliotheken genoemd in UNIX-besturingssystemen, zijn een van de handigste soorten Windows-onderdelen. U kunt ze gebruiken om code en resources te delen en om de grootte van uw apps te verkleinen. DLL's kunnen het zelfs eenvoudiger maken om uw apps te onderhouden en uit te breiden.
In dit scenario maakt u een DLL waarmee een aantal wiskundige functies worden geïmplementeerd. Vervolgens maakt u een console-app die gebruikmaakt van de functies uit het DLL-bestand. U krijgt ook een inleiding tot enkele programmeertechnieken en conventies die worden gebruikt in Windows-DLL's.
In deze handleiding worden de volgende stappen doorlopen:
- Maak een DLL-project in Visual Studio.
- Voeg geëxporteerde functies en variabelen toe aan het DLL-bestand.
- Maak een console-app-project in Visual Studio.
- Gebruik de functies en variabelen die zijn geïmporteerd uit het DLL-bestand in de console-app.
- Voer de voltooide app uit.
Net als bij een statisch gekoppelde bibliotheek exporteert een DLL-bestand variabelen, functies en resources op naam. Een client-app importeert de namen om deze variabelen, functies en resources te gebruiken. In tegenstelling tot een statisch gekoppelde bibliotheek verbindt Windows de importbewerkingen in uw app met de exports in een DLL tijdens het laden of tijdens runtime, in plaats van ze te verbinden tijdens het koppelen. Windows vereist extra informatie die geen deel uitmaakt van het standaard C++-compilatiemodel om deze verbindingen te maken. De MSVC-compiler implementeert enkele Microsoft-specifieke extensies voor C++ om deze extra informatie te bieden. We leggen deze extensies uit naarmate we verdergaan.
In dit scenario worden twee Visual Studio-oplossingen gemaakt: een oplossing waarmee het DLL-bestand wordt gebouwd en één waarmee de client-app wordt gebouwd. Het DLL-bestand maakt gebruik van de C-aanroepconventie. Het kan worden aangeroepen vanuit apps die zijn geschreven in andere programmeertalen, zolang het platform, de aanroepende conventies en het koppelen van conventies overeenkomen. De client-app maakt gebruik van impliciete koppeling, waarbij Windows de app koppelt aan het DLL-bestand tijdens het laden. Door deze koppeling kan de app de door dll geleverde functies aanroepen, net zoals de functies in een statisch gekoppelde bibliotheek.
In deze handleiding worden sommige veelvoorkomende situaties niet behandeld. In de code wordt het gebruik van C++-DLL's door andere programmeertalen niet weergegeven. Er wordt niet getoond hoe u een DLL met alleen resources maakt of hoe u expliciete koppelingen gebruikt om DLL's tijdens runtime te laden in plaats van tijdens de laadtijd. Wees gerust, u kunt MSVC en Visual Studio gebruiken om al deze dingen te doen.
Hoewel de code van het DLL-bestand is geschreven in C++, gebruiken we C-stijlinterfaces voor de geëxporteerde functies. Er zijn twee belangrijke redenen hiervoor: Ten eerste ondersteunen veel andere talen het importeren van C-functies. De client-app hoeft niet te worden geschreven in C++. Ten tweede worden enkele veelvoorkomende valkuilen met betrekking tot geëxporteerde klassen en lidfuncties vermeden. Het is eenvoudig om fouten te maken die moeilijk te diagnosticeren zijn bij het exporteren van klassen, omdat alles waarnaar in een klassedeclaratie wordt verwezen een geïmporteerde instantie moet hebben. Deze beperking is van toepassing op DLL's, maar niet op statische bibliotheken. Als uw klassen in de stijl van 'plain-old-data' zijn, zou u dit probleem niet tegenkomen.
Zie C/C++ DLL's maken in Visual Studio voor meer informatie over DLL's. Zie Bepalen welke koppelingsmethode moet worden gebruikt voor meer informatie over impliciete koppelingen en expliciete koppelingen. Zie C++- functies exporteren voor gebruik in uitvoerbare bestanden in de C-taal voor informatie over het maken van C++-DLL's voor gebruik met programmeertalen die gebruikmaken van koppelingsconventies in C++. Zie DLL-functies aanroepen vanuit Visual Basic Applications voor informatie over het maken van DLL-bestanden voor gebruik met .NET-talen.
Vereiste voorwaarden
- Microsoft Windows 7 of hoger. We raden de nieuwste versie van Windows aan voor de beste ontwikkelervaring.
Visual Studio. Zie Visual Studio installeren voor meer informatie over het downloaden en installeren van Visual Studio. Wanneer u het installatieprogramma uitvoert, moet u ervoor zorgen dat de desktopontwikkeling met de C++ -workload is gecontroleerd. U hoeft zich geen zorgen te maken als u deze workload niet hebt geïnstalleerd toen u Visual Studio hebt geïnstalleerd. U kunt het installatieprogramma opnieuw uitvoeren en het nu installeren.
- Visual Studio. Zie Visual Studio 2015 installeren voor meer informatie over het downloaden en installeren van Visual Studio 2015. Gebruik een aangepaste installatie om de C++-compiler en hulpprogramma's te installeren, omdat deze niet standaard zijn geïnstalleerd.
Een goed begrip van de basisprincipes van het gebruik van de Visual Studio IDE. Als u eerder Windows-bureaublad-apps hebt gebruikt, kunt u het waarschijnlijk bijhouden. Zie Visual Studio IDE-functierondleiding voor een inleiding.
Enige bekendheid met de C++-taal. Maak je geen zorgen, we doen niets te ingewikkeld.
Opmerking
In dit scenario wordt ervan uitgegaan dat u Visual Studio 2017 versie 15.9 of hoger gebruikt. Sommige eerdere versies van Visual Studio 2017 hadden defecten in de codesjablonen of gebruikten verschillende dialoogvensters voor de gebruikersinterface. Als u problemen wilt voorkomen, gebruikt u het installatieprogramma van Visual Studio om Visual Studio 2017 bij te werken naar versie 15.9 of hoger.
Het DLL-project maken
In de volgende set taken maakt u een project voor uw DLL, voegt u code toe en bouwt u het. Als u wilt beginnen, start u de Visual Studio IDE en meldt u zich aan als dat nodig is. De instructies variëren enigszins, afhankelijk van de versie van Visual Studio die u gebruikt. Als u de stappen voor de gewenste versie van Visual Studio wilt zien, gebruikt u de versieselector boven aan de inhoudsopgave op deze pagina.
Een DLL-project maken in Visual Studio
Kies bestand>nieuw>project op de menubalk om het dialoogvenster Nieuw project maken te openen.
Stel bovenaan het dialoogvenster Taal in op C++, stel Platform in op Windows en stel Projecttype in op Bibliotheek.
Selecteer dynamic-link library (DLL) in de gefilterde lijst met projecttypen en kies vervolgens Volgende.
Voer op de pagina Uw nieuwe project configurerenMathLibrary in het vak Projectnaam in om een naam voor het project op te geven. Laat de standaardwaarden voor de locatie - en oplossingsnaam staan . Stel oplossing in op Nieuwe oplossing maken. Schakel de optie Oplossing plaatsen en project in dezelfde map uit als deze is ingeschakeld.
Kies de knop Maken om het project te maken.
Wanneer de oplossing is gemaakt, ziet u het gegenereerde project en de bronbestanden in het venster Solution Explorer in Visual Studio.
Een DLL-project maken in Visual Studio 2017
Kies bestand>nieuw>project op de menubalk om het dialoogvenster Nieuw project te openen.
In het linkerdeelvenster van het dialoogvenster Nieuw project selecteer Geïnstalleerd>Visual C++>Windows Desktop. Selecteer Dynamic-Link Bibliotheek (DLL) in het middelste deelvenster. Voer MathLibrary in het vak Naam in om een naam voor het project op te geven. Laat de standaardwaarden voor de locatie - en oplossingsnaam staan . Stel oplossing in op Nieuwe oplossing maken. Selecteer Map maken voor oplossing als het niet is aangevinkt.
Kies de knop OK om het project te maken.
Wanneer de oplossing is gemaakt, ziet u het gegenereerde project en de bronbestanden in het venster Solution Explorer in Visual Studio.
Een DLL-project maken in Visual Studio 2015 en oudere versies
Kies Bestand>nieuw>project op de menubalk.
Vouw in het linkerdeelvenster van het dialoogvenster Nieuw projectgeïnstalleerde>sjablonen uit en selecteer Visual C++ en selecteer vervolgens in het middelste deelvenster Win32-consoletoepassing. Voer MathLibrary in het invoervak Naam in om een naam voor het project op te geven. Laat de standaardwaarden voor de locatie - en oplossingsnaam staan . Stel oplossing in op Nieuwe oplossing maken. Controleer Maak map voor oplossing als deze niet is aangevinkt.
Kies de knop OK om het dialoogvenster Nieuw project te sluiten en de wizard Win32-toepassing te starten.
Kies de knop Volgende . Selecteer DLL op de pagina Toepassingsinstellingen onder Toepassingstype.
Kies de knop Voltooien om het project te maken.
Wanneer de wizard de oplossing voltooit, ziet u het gegenereerde project en de bronbestanden in het venster Solution Explorer in Visual Studio.
Op dit moment doet deze DLL niet veel. Vervolgens maakt u een headerbestand om de functies te declareren die uw DLL exporteert en voegt u vervolgens de functiedefinities toe aan het DLL-bestand om het nuttiger te maken.
Een headerbestand toevoegen aan het DLL-bestand
Als u een koptekstbestand voor uw functies wilt maken, kiest u op de menubalk Project>Add New Item.
Selecteer Visual C++ in het dialoogvenster Nieuw item toevoegen in het linkerdeelvenster. Selecteer in het middelste deelvenster headerbestand (.h). Geef
MathLibrary.hop als de naam voor het headerbestand.
Kies de knop Toevoegen om een leeg headerbestand te genereren, dat wordt weergegeven in een nieuw editorvenster.
Vervang de inhoud van het headerbestand door deze 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();
Dit headerbestand declareert enkele functies voor het produceren van een gegeneraliseerde Fibonacci-reeks, op basis van twee initiële waarden. Een aanroep naar fibonacci_init(1, 1) genereert de bekende Fibonacci-getallenreeks.
Let op de preprocessorinstructies boven aan het bestand. De nieuwe projectsjabloon voor een DLL-project voegt <PROJECTNAME>_EXPORTS toe aan de gedefinieerde preprocessormacro's. In dit voorbeeld definieert Visual Studio MATHLIBRARY_EXPORTS wanneer uw MathLibrary DLL-project wordt gebouwd.
Wanneer de MATHLIBRARY_EXPORTS macro is gedefinieerd, stelt de MATHLIBRARY_API macro de __declspec(dllexport) wijzigingsfunctie in op de functiedeclaraties. Deze wijzigingsfunctie vertelt de compiler en linker om een functie of variabele uit het DLL-bestand te exporteren voor gebruik door andere toepassingen. Wanneer MATHLIBRARY_EXPORTS niet is gedefinieerd, bijvoorbeeld wanneer het headerbestand door een clienttoepassing wordt opgenomen, wordt MATHLIBRARY_API de __declspec(dllimport) modifier toegepast op de declaraties. Deze wijzigingsfunctie optimaliseert het importeren van de functie of variabele in een toepassing. Zie dllexport, dllimport voor meer informatie.
Een implementatie toevoegen aan het DLL-bestand
Klik in Solution Explorer met de rechtermuisknop op het knooppunt Bronbestanden en kiesNieuw item>. Maak een nieuw
.cppbestand met de naamMathLibrary.cpp, op dezelfde manier dat u in de vorige stap een nieuw headerbestand hebt toegevoegd.Selecteer in het editorvenster het
MathLibrary.cpptabblad als het al is geopend. Als dat niet het probleem is, dubbelklikt u in Solution Explorer opMathLibrary.cppde map Bronbestanden van het project MathLibrary om het te openen.Vervang in de editor de inhoud van het
MathLibrary.cppbestand door de volgende 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_; }
Selecteer in het editorvenster het tabblad voor MathLibrary.cpp als deze al is geopend. Als dat niet het probleem is, dubbelklikt u in Solution Explorer op MathLibrary.cpp in de map Bronbestanden van het project MathLibrary om het te openen.
Vervang in de editor de inhoud van het
MathLibrary.cppbestand door de volgende 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_; }
Compileer het DLL-bestand om te controleren of alles tot nu toe werkt. Kies Build Build>Solution op de menubalk om te compileren. De DLL en gerelateerde compileruitvoer worden geplaatst in een map die direct onder de oplossingsmap heet Debug. Als u een release-build maakt, wordt de uitvoer geplaatst in een map met de naam Release. De uitvoer zou er ongeveer zo uit moeten zien:
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 ==========
Gefeliciteerd, u hebt een DLL gemaakt met Visual Studio. Vervolgens maakt u een client-app die gebruikmaakt van de functies die door het DLL-bestand worden geëxporteerd.
Een client-app maken die gebruikmaakt van het DLL-bestand
Wanneer u een DLL maakt, moet u nadenken over hoe client-apps deze kunnen gebruiken. Als u de functies wilt aanroepen of toegang wilt krijgen tot de gegevens die zijn geëxporteerd door een DLL, moet de broncode van de client de declaraties beschikbaar hebben tijdens het compileren. Tijdens de koppeling vereist de linker informatie om de functie-aanroepen of gegevenstoegang op te lossen. Een DLL levert deze informatie in een importbibliotheek, een bestand met informatie over het vinden van de functies en gegevens, in plaats van de werkelijke code. En tijdens runtime moet het DLL-bestand beschikbaar zijn voor de client, op een locatie die het besturingssysteem kan vinden.
Of het nu uw eigen project of van een derde partij is, uw client-app-project heeft verschillende stukjes informatie nodig om een DLL te gebruiken. Er moeten de headers worden gevonden die de DLL-exports declareren, de importbibliotheken voor de linker en het DLL-bestand zelf. Eén oplossing is het kopiëren van al deze bestanden naar uw clientproject. Voor DLL's van derden die waarschijnlijk niet veranderen terwijl uw client in ontwikkeling is, is deze methode mogelijk de beste manier om ze te gebruiken. Wanneer u echter ook de DLL bouwt, is het beter om duplicatie te voorkomen. Als u een lokale kopie maakt van DLL-bestanden die in ontwikkeling zijn, kunt u per ongeluk een headerbestand in de ene kopie wijzigen, maar niet de andere, of een verouderde bibliotheek gebruiken.
Als u niet-gesynchroniseerde code wilt voorkomen, raden we u aan het insluitingspad in uw clientproject in te stellen om de DLL-headerbestanden rechtstreeks vanuit uw DLL-project op te nemen. Stel ook het bibliotheekpad in uw clientproject in om de DLL-importbibliotheken uit het DLL-project op te nemen. Kopieer ten slotte de ingebouwde DLL van het DLL-project naar de uitvoermap van de client. Met deze stap kan uw client-app dezelfde DLL-code gebruiken die u bouwt.
Een client-app maken in Visual Studio
Kies bestand>nieuw>project op de menubalk om het dialoogvenster Een nieuw project maken te openen.
Stel bovenaan het dialoogvenster Taal in op C++, stel Platform in op Windows en stel Projecttype in op Console.
Kies Console-app in de gefilterde lijst met projecttypen en kies vervolgens Volgende.
Voer op de pagina Uw nieuwe project configurerenMathClient in het vak Projectnaam in om een naam voor het project op te geven. Laat de standaardwaarden voor de locatie - en oplossingsnaam staan . Stel oplossing in op Nieuwe oplossing maken. Schakel de optie Oplossing plaatsen en project in dezelfde map uit als deze is ingeschakeld.
Kies de knop Maken om het clientproject te maken.
Er wordt een simpel consoletoepassingsproject voor u gemaakt. De naam voor het hoofdbronbestand is hetzelfde als de projectnaam die u eerder hebt ingevoerd. In dit voorbeeld heeft deze de naam MathClient.cpp. U kunt het bouwen, maar het maakt nog geen gebruik van uw DLL.
Een client-app maken in Visual Studio 2017
Als u een C++-app wilt maken die gebruikmaakt van het DLL-bestand dat u hebt gemaakt, kiest u bestand>nieuw>project op de menubalk.
Selecteer In het linkerdeelvenster van het dialoogvenster Nieuw projectWindows Desktop onder Geïnstalleerde>Visual C++. Selecteer windows-consoletoepassing in het middelste deelvenster. Geef de naam op voor het project, MathClient, in het invoervak Naam . Laat de standaardwaarden voor de locatie - en oplossingsnaam staan . Stel oplossing in op Nieuwe oplossing maken. Controleer map maken voor oplossing als deze niet is ingeschakeld.
Kies OK om het client-app-project te maken.
Er is een minimaal console-applicatieproject voor jou gemaakt. De naam voor het hoofdbronbestand is hetzelfde als de projectnaam die u eerder hebt ingevoerd. In dit voorbeeld heeft deze de naam MathClient.cpp. U kunt het bouwen, maar het maakt nog geen gebruik van uw DLL.
Een client-app maken in Visual Studio 2015
Als u een C++-app wilt maken die gebruikmaakt van het DLL-bestand dat u hebt gemaakt, kiest u bestand>nieuw>project op de menubalk.
Selecteer In het linkerdeelvenster van het dialoogvenster Nieuw projectWin32 onder Geïnstalleerde>sjablonen>visual C++. Selecteer in het middelste deelvenster Win32-consoletoepassing. Geef de naam op voor het project, MathClient, in het invoervak Naam . Laat de standaardwaarden voor de locatie - en oplossingsnaam staan . Stel oplossing in op Nieuwe oplossing maken. Controleer directory maken voor oplossing als deze niet is geselecteerd.
Kies de knop OK om het dialoogvenster Nieuw project te sluiten en de wizard Win32-toepassing te starten. Kies op de pagina Overzicht van het dialoogvenster Wizard Win32-toepassing de knop Volgende .
Selecteer op de pagina Toepassingsinstellingen onder Toepassingstypeconsoletoepassing als deze nog niet is geselecteerd.
Kies de knop Voltooien om het project te maken.
Wanneer de wizard klaar is, wordt er een eenvoudig consoletoepassingsproject voor u gemaakt. De naam voor het hoofdbronbestand is hetzelfde als de projectnaam die u eerder hebt ingevoerd. In dit voorbeeld heeft deze de naam MathClient.cpp. U kunt het bouwen, maar het maakt nog geen gebruik van uw DLL.
Als u vervolgens de MathLibrary-functies in uw broncode wilt aanroepen, moet uw project het MathLibrary.h bestand bevatten. U kunt dit headerbestand kopiëren naar uw client-app-project en dit vervolgens als een bestaand item toevoegen aan het project. Deze methode kan een goede keuze zijn voor bibliotheken van derden. Als u echter tegelijkertijd aan de code voor uw DLL en de client werkt, kunnen de headerbestanden niet meer worden gesynchroniseerd. Om dit probleem te voorkomen, stelt u het pad Extra inclusief mappen in uw project in om het pad naar de oorspronkelijke koptekst op te nemen.
Om de DLL-header aan uw inclusiepad toe te voegen
Klik met de rechtermuisknop op het knooppunt MathClient in Solution Explorer om het dialoogvenster Eigenschappenpagina's te openen.
Selecteer in de vervolgkeuzelijst Configuratiealle configuraties als deze nog niet is geselecteerd.
Selecteer in het linkerdeelvenster Configuratie-eigenschappen>C/C++>Algemeen.
Selecteer in het eigenschappenvenster de vervolgkeuzelijst naast het invoervak Extra inclusief mappen en kies Bewerken.
Dubbelklik bovenin het deelvenster van het dialoogvenster Aanvullende Include Mappen om een bewerkingselement in te schakelen. Of klik op het mappictogram om een nieuwe vermelding te maken.
Geef in het bewerkingsvak het pad op naar het
MathLibrary.h-headerbestand. U kunt het beletseltekenbesturingselement (...) kiezen om naar de juiste map te bladeren.U kunt ook een relatief pad van uw clientbronbestanden invoeren naar de map die de DLL-headerbestanden bevat. Als u de aanwijzingen hebt gevolgd om uw clientproject in een afzonderlijke oplossing van het DLL-bestand te plaatsen, moet het relatieve pad er als volgt uitzien:
..\..\MathLibrary\MathLibraryAls uw DLL- en clientprojecten zich in dezelfde oplossing bevinden, kan het relatieve pad er als volgt uitzien:
..\MathLibraryWanneer de DLL- en clientprojecten zich in andere mappen bevinden, past u het relatieve pad aan zodat het overeenkomt. U kunt ook het knop met het beletselteken gebruiken om naar de map te bladeren.
Nadat u het pad naar het koptekstbestand hebt ingevoerd in het dialoogvenster Extra mappen opnemen , kiest u de knop OK . Kies in het dialoogvenster Eigenschappenpagina's de knop OK om uw wijzigingen op te slaan.
U kunt nu het MathLibrary.h bestand opnemen en de functies gebruiken die het declareert in uw clienttoepassing. Vervang de inhoud van MathClient.cpp door deze code te gebruiken:
// 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;
}
Deze code kan worden gecompileerd, maar niet gekoppeld. Als u de client-app nu bouwt, worden in de foutenlijst verschillende LNK2019 fouten weergegeven. Dat komt doordat er bepaalde gegevens ontbreken in uw project: u hebt nog niet opgegeven dat uw project afhankelijk is van de MathLibrary.lib bibliotheek. En u hebt de linker niet verteld hoe u het MathLibrary.lib bestand kunt vinden.
U kunt dit probleem oplossen door het bibliotheekbestand rechtstreeks naar uw client-app-project te kopiëren. De linker zou deze automatisch vinden en gebruiken. Als de bibliotheek en de client-app echter in ontwikkeling zijn, kan dit leiden tot wijzigingen in de ene kopie die niet in de andere kopie worden weergegeven. Om dit probleem te voorkomen, kunt u de eigenschap Aanvullende afhankelijkheden instellen om het buildsysteem te laten weten dat uw project afhankelijk MathLibrary.libis. En u kunt een pad naar extra bibliotheekmappen in uw project instellen om het pad naar de oorspronkelijke bibliotheek op te nemen wanneer u een koppeling maakt.
De DLL-importbibliotheek toevoegen aan uw project
Klik met de rechtermuisknop op het knooppunt MathClient in Solution Explorer en kies Eigenschappen om het dialoogvenster Eigenschappenpagina's te openen.
Selecteer in de vervolgkeuzelijst Configuratiealle configuraties als deze nog niet is geselecteerd. Het zorgt ervoor dat wijzigingen in eigenschappen van toepassing zijn op zowel Debug als Release builds.
Selecteer in het linkerdeelvenster Configuratie-eigenschappen>Linker>Invoer. Selecteer in het eigenschappenvenster de vervolgkeuzelijst naast het invoervak Aanvullende afhankelijkheden en kies Bewerken.
Voeg in het dialoogvenster
MathLibrary.libtoe aan de lijst in het bovenste bewerkbesturingselement.
Kies OK om terug te gaan naar het dialoogvenster Eigenschappenpagina's .
Selecteer in het linkerdeelvenster Configuratie-eigenschappen>linker>algemeen. Selecteer in het eigenschappenvenster de vervolgkeuzelijst naast het invoervak Aanvullende bibliotheekmappen en kies Bewerken.
Dubbelklik in het bovenste deelvenster van het dialoogvenster Extra bibliotheekmappen om een bewerkingscontrole te activeren. Geef in het bewerkingsveld het pad op naar de locatie van het
MathLibrary.libbestand. Standaard bevindt deze zich in een map met de naam Debug rechtstreeks onder de DLL-oplossingsmap. Als u een release-build maakt, wordt het bestand in een map met de naam Release geplaatst. U kunt de$(IntDir)macro gebruiken zodat de linker uw DLL kan vinden, ongeacht welk type build u maakt. Als u de aanwijzingen hebt gevolgd om uw clientproject in een afzonderlijke oplossing van het DLL-project te plaatsen, moet het relatieve pad er als volgt uitzien:..\..\MathLibrary\$(IntDir)Als uw DLL- en clientprojecten zich op andere locaties bevinden, past u het relatieve pad aan zodat het overeenkomt.
Nadat u het pad naar het bibliotheekbestand hebt ingevoerd in het dialoogvenster Aanvullende bibliotheekmappen , kiest u de knop OK om terug te gaan naar het dialoogvenster Eigenschappenpagina's . Kies OK om de eigenschapswijzigingen op te slaan.
Uw client-app kan nu worden gecompileerd en gekoppeld, maar heeft nog steeds niet alles wat nodig is om uit te voeren. Wanneer het besturingssysteem uw app laadt, zoekt het naar de MathLibrary DLL. Als het DLL-bestand niet kan worden gevonden in bepaalde systeemmappen, het omgevingspad of de lokale app-map, mislukt het laden. Afhankelijk van het besturingssysteem ziet u een foutbericht als volgt:
U kunt dit probleem voorkomen door het DLL-bestand te kopiëren naar de map die het uitvoerbare bestand van de client bevat als onderdeel van het buildproces. U kunt een gebeurtenis na de build toevoegen aan uw project om een opdracht toe te voegen waarmee het DLL-bestand wordt gekopieerd naar de uitvoermap van uw build. Met de opdracht die hier is opgegeven, wordt de DLL alleen gekopieerd als deze ontbreekt of is gewijzigd. Er worden macro's gebruikt om te kopiëren naar en van de locaties voor foutopsporing of release, op basis van uw buildconfiguratie.
Het DLL-bestand kopiëren in een gebeurtenis na de build
Klik met de rechtermuisknop op het knooppunt MathClient in Solution Explorer en kies Eigenschappen om het dialoogvenster Eigenschappenpagina's te openen.
Selecteer alle configuraties in de vervolgkeuzelijst Configuratie als deze nog niet is geselecteerd.
Selecteer in het linkerdeelvenster Configuratie-eigenschappen>Buildgebeurtenissen>Post-Buildgebeurtenis.
Selecteer in het Eigenschappenvenster het bewerkingsveld in het veld Opdrachtregel. Als u de aanwijzingen hebt gevolgd om uw clientproject in een afzonderlijke oplossing van het DLL-project te plaatsen, voert u deze opdracht in:
xcopy /y /d "..\..\MathLibrary\$(IntDir)MathLibrary.dll" "$(OutDir)"Als uw DLL- en clientprojecten zich in andere mappen bevinden, moet u het relatieve pad naar het DLL-bestand wijzigen zodat het klopt met de nieuwe locatie.
Kies de knop OK om uw wijzigingen op te slaan in de projecteigenschappen.
Uw client-app heeft nu alles wat nodig is om te bouwen en uit te voeren. Bouw de toepassing door Build>Oplossing bouwen te kiezen op de menubalk. Het uitvoervenster in Visual Studio moet ongeveer als het volgende voorbeeld hebben, afhankelijk van uw versie van Visual Studio:
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 ==========
Gefeliciteerd, u hebt een toepassing gemaakt waarmee functies in uw DLL worden aangeroepen. Voer nu uw toepassing uit om te zien wat deze doet. Kies In de menubalk de optie Foutopsporing>starten zonder foutopsporing. Visual Studio opent een opdrachtvenster waarin het programma kan worden uitgevoerd. Het laatste deel van de uitvoer moet er als volgt uitzien:
Druk op een willekeurige toets om het opdrachtvenster te sluiten.
Nu u een DLL en een clienttoepassing hebt gemaakt, kunt u experimenteren. Stel onderbrekingspunten in de code van de client-app in en voer de app uit in het foutopsporingsprogramma. Bekijk wat er gebeurt wanneer u stapt in een bibliotheekoproep. Voeg andere functies toe aan de bibliotheek of schrijf een andere client-app die gebruikmaakt van uw DLL.
Wanneer u uw app implementeert, moet u ook de DLL's implementeren die worden gebruikt. De eenvoudigste manier om de DLL's die u bouwt of die u opneemt van derden beschikbaar te maken, is door ze in dezelfde map te plaatsen als uw app. Dit wordt ook wel lokale implementatie van apps genoemd. Zie Implementatie in Microsoft C++voor meer informatie over implementatie.