Delen via


Stapsgewijze handleiding: STL-bibliotheken importeren als kopteksteenheden

In dit overzicht ziet u hoe u STL-bibliotheken (Standard Template Library) in C++ importeert als header-eenheden in Visual Studio. Zie Zelfstudie: De C++-standaardbibliotheek importeren met behulp van modules voor een nog snellere en krachtigere manier om de standaardbibliotheek van C++ te importeren.

Het importeren van een STL-header als een header-eenheid is eenvoudiger dan het gebruik van vooraf gecompileerde headerbestanden. Header-eenheden zijn eenvoudiger in te stellen en te gebruiken, zijn aanzienlijk kleiner op schijf, bieden vergelijkbare prestatievoordelen en zijn flexibeler dan een gedeelde PCH.

Zie Wat is een header-eenheid? Voor meer gedetailleerde informatie over wat header-eenheden zijn en wat de voordelen zijn die ze bieden. Als u kopteksteenheden wilt contrasteren met andere manieren om de standaardbibliotheek te importeren, raadpleegt u Kopteksteenheden, modules en vooraf gecompileerde headers vergelijken.

Vereiste voorwaarden

Als u kopteksteenheden wilt gebruiken, gebruikt u Visual Studio 2022 of hoger of Visual Studio 2019 versie 16.11 of hoger. De /std:c++20 optie (of een latere versie) is vereist voor het gebruik van header-eenheden.

Twee benaderingen voor het importeren van STL-headers als header-eenheden

Voordat u een STL-header kunt importeren, moet deze worden gecompileerd in een header-eenheid. Een header-eenheid is een binaire weergave van een headerbestand. Het heeft een .ifc extensie.

De aanbevolen methode is om een statische bibliotheek te maken die de ingebouwde headereenheden voor de STL-headers bevat die u wilt gebruiken. Verwijs vervolgens naar die bibliotheek en import de bijbehorende header-eenheden. Deze aanpak kan leiden tot snellere builds en beter hergebruik. Zie Methode 1: Een statische bibliotheek met STL-bibliotheekheadereenheden maken om deze aanpak uit te proberen.

Een andere benadering is om Visual Studio te laten scannen op de STL-headers die u #include in uw project hebt, deze te compileren tot header-eenheden en import te gebruiken in plaats van #include in die headers. Deze methode is handig als u een grote codebasis hebt, omdat u uw broncode niet hoeft te wijzigen. Deze benadering is minder flexibel dan de statische bibliotheekbenadering, omdat deze zich niet leent voor het hergebruik van de ingebouwde header-eenheden in andere projecten. Maar u krijgt nog steeds het prestatievoordeel van het importeren van STL-bibliotheken als afzonderlijke header-eenheden. Als u deze aanpak wilt uitproberen, zie Benadering 2: Scan voor STL-headers om te importeren.

Benadering 1: Een statische bibliotheek met STL-bibliotheekheadereenheden maken

De aanbevolen manier om STL-bibliotheken als header-eenheden te gebruiken, is door een of meer statische bibliotheekprojecten te maken. Deze projecten moeten bestaan uit de kopeenheden van de STL-bibliotheek die u wilt gebruiken. Verwijs vervolgens naar de bibliotheekprojecten om deze STL-headereenheden te gebruiken. Het is vergelijkbaar met het gebruik van gedeelde vooraf gecompileerde headers, maar eenvoudiger.

Header-units (en modules) die zijn gebouwd in een statisch bibliotheekproject, zijn automatisch beschikbaar voor verwijzende projecten omdat het projectsysteem automatisch de juiste /headerUnit opdrachtregeloptie toevoegt aan de compiler, zodat verwijzende projecten de header-units kunnen importeren.

Deze methode zorgt ervoor dat de header-eenheid voor een bepaalde header slechts één keer wordt gebouwd. Hiermee kunt u enkele of alle header-eenheden importeren, wat niet mogelijk is met een PCH. U kunt kopregels in elke volgorde opnemen.

In het volgende voorbeeld maakt u een statische bibliotheek die bestaat uit de <iostream> en <vector> header-eenheden. Nadat de oplossing is gemaakt, verwijst u naar dit gedeelde headereenheidproject vanuit een ander C++-project. Overal waar import <iostream>; of import <vector>; wordt gevonden, wordt in plaats van de header met de preprocessor te vertalen, de ingebouwde header-eenheid voor die bibliotheek gebruikt. Het verbetert de buildprestaties, zoals PCH-bestanden, wanneer dezelfde header is opgenomen in meerdere bestanden. De header hoeft niet telkens opnieuw te worden verwerkt door de bestanden die deze bevatten. In plaats daarvan wordt de reeds verwerkte gecompileerde header-eenheid geïmporteerd.

Voer de volgende stappen uit om een statische bibliotheek te maken die de STL-bibliotheken <iostream><vector>bevat:

  1. Maak een leeg C++-project. Geef het de naam SharedPrj.
    Selecteer Leeg project voor C++ in de projecttypen die beschikbaar zijn in het venster Een nieuw project maken : Schermopname van het maken van een nieuw leeg C++-project.

  2. Voeg een nieuw C++-bestand toe aan het project. Wijzig de inhoud van het bestand in:

    import <iostream>;
    import <vector>;
    

Projecteigenschappen instellen

Stel projecteigenschappen in om de header-eenheden van dit project te delen.

  1. Selecteer in het hoofdmenu van Visual Studio Project>SharedPrj Properties om het dialoogvenster projecteigenschappenpagina's te openen: Schermopname met instellingen voor configuratietype en C++ Taalstandaard.
  2. Selecteer Alle configuraties in de vervolgkeuzelijst Configuratie en selecteer vervolgens Alle platforms in de vervolgkeuzelijst Platform . Deze instellingen zorgen ervoor dat uw wijzigingen van toepassing zijn, ongeacht of u bouwt voor foutopsporing of release.
  3. Selecteer in het linkerdeelvenster van het dialoogvenster Eigenschappenpagina's van het project de optie Configuratie-eigenschappen>algemeen.
  4. Wijzig de optie Configuratietype in statische bibliotheek (.lib).
  5. Wijzig de C++-taalstandaard in ISO C++20 Standard (/std:c++20) (of hoger).
  6. Selecteer in het linkerdeelvenster van het dialoogvenster Projecteigenschappen configuratie-eigenschappen>C/C++>Algemeen.
  7. Selecteer Ja in de vervolgkeuzelijst Scanbronnen voor moduleafhankelijkheden. (Deze optie zorgt ervoor dat de compiler uw code scant op afhankelijkheden die kunnen worden ingebouwd in headereenheden): Schermopname van de instelling van de eigenschap afhankelijkheden van de scanmodule.
  8. Kies OK om het dialoogvenster Eigenschappenpagina's van het project te sluiten. Bouw de oplossing door Bouwen>Oplossing bouwen te selecteren in het hoofdmenu.

Verwijzen naar de header-eenheidsbibliotheek

Om <iostream> en <vector> als kopteksteenheden vanuit de statische bibliotheek te importeren, maakt u een project dat als volgt naar de statische bibliotheek verwijst:

  1. Als de huidige oplossing nog steeds is geopend, selecteert u bestand>toevoegen>nieuw project in het menu van Visual Studio.

  2. Selecteer in de wizard Een nieuw project maken de sjabloon voor de C++ -console-app en kies Volgende.

  3. Geef het nieuwe project de naam Walkthrough. Wijzig de vervolgkeuzelijst Oplossing in Toevoegen aan de oplossing. Kies Maken om het project te maken en toe te voegen aan uw oplossing.

  4. Wijzig de inhoud van het Walkthrough.cpp bronbestand als volgt:

    import <iostream>;
    import <vector>;
    
    int main()
    {
        std::vector<int> numbers = {0, 1, 2};
        std::cout << numbers[1];
    }
    

Voor headerunits zijn de /std:c++20 optie (of hoger) vereist. Stel de taalstandaard in met behulp van de volgende stappen:

  1. Klik in Solution Explorer met de rechtermuisknop op het walkthrough-project en selecteer Eigenschappen om het dialoogvenster Projecteigenschappenpagina's te openen: Schermopname van het instellen van de taalstandaard op de preview-versie.
  2. Selecteer in het linkerdeelvenster van het dialoogvenster Eigenschappenpagina's van het Walkthrough-project de optie Configuratie-eigenschappen>Algemeen.
  3. Selecteer in de vervolgkeuzelijst C++ Language StandardISO C++20 Standard (/std:c++20) (of hoger).
  4. Kies OK om het dialoogvenster Eigenschappenpagina's van het project te sluiten.

Voeg in het walkthrough-project een verwijzing toe naar het SharedPrj-project met de volgende stappen:

  1. Selecteer in het walkthrough-project het knooppunt Verwijzingen en selecteer vervolgens Verwijzing toevoegen. Selecteer SharedPrj in de lijst met projecten: Schermopname van het dialoogvenster Verwijzing toevoegen. Het wordt gebruikt om een verwijzing naar het walkthrough-project toe te voegen. Door deze verwijzing toe te voegen, wordt het buildsysteem gebruikt van de header-eenheden die zijn gebouwd door SharedPrj wanneer een import in het walkthrough-project overeenkomt met een van de ingebouwde header-eenheden in SharedPrj.
  2. Kies OK om het dialoogvenster Verwijzing toevoegen te sluiten.
  3. Klik met de rechtermuisknop op het walkthrough-project en selecteer Instellen als opstartproject.
  4. Bouw de oplossing. (Build gebruiken>Oplossing bouwen in het hoofdmenu.) Voer het uit om te zien dat de verwachte uitvoer wordt geproduceerd: 1

Het voordeel van deze benadering is dat u vanuit elk project naar het statische bibliotheekproject kunt verwijzen om de header-units opnieuw te gebruiken. In dit voorbeeld bevat de statische bibliotheek de <vector> en <iostream> header-eenheden.

U kunt een monolithisch statisch bibliotheekproject maken dat alle veelgebruikte STL-headers bevat die u wilt importeren uit uw verschillende projecten. U kunt ook kleinere gedeelde bibliotheekprojecten maken voor de verschillende groepen van STL-bibliotheken die u als header-eenheden wilt importeren. Verwijs vervolgens naar deze gedeelde headereenheidprojecten indien nodig.

Het resultaat moet de builddoorvoer verhogen omdat het importeren van een header-eenheid aanzienlijk vermindert het werk dat de compiler moet uitvoeren.

Wanneer u deze benadering met uw eigen projecten gebruikt, bouwt u het statische bibliotheekproject met compileropties die compatibel zijn met het project dat ernaar verwijst. STL-projecten moeten bijvoorbeeld worden gebouwd met de /EHsc compileroptie om de verwerking van uitzonderingen in te schakelen, en ook de projecten die naar het statische bibliotheekproject verwijzen.

Gebruik /translateInclude

Met de /translateInclude compileroptie (beschikbaar in het dialoogvenster Eigenschappenpagina's van het project onder C/C++>General>Translate Includes to Imports) kunt u eenvoudiger een kopteksteenheidbibliotheek gebruiken in oudere projecten die #include de STL-bibliotheken bevatten. Het is niet nodig om de #include instructies in uw project te wijzigen naar import, terwijl u nog steeds het voordeel krijgt van het importeren van de header-eenheden in plaats van ze op te nemen.

Als u bijvoorbeeld #include <vector> in uw project hebt en een statische bibliotheek verwijst die een header-eenheid voor <vector> bevat, hoeft u #include <vector> in uw broncode niet handmatig naar import <vector>; te veranderen. In plaats daarvan behandelt de compiler #include <vector> automatisch als import <vector>;. Zie voor meer gedetailleerde informatie over deze aanpak Benadering 2: Scannen van includes voor STL-headers om te importeren. Niet alle STL-headerbestanden kunnen worden gecompileerd naar een header-eenheid. De header-units.json die met Visual Studio wordt geleverd, geeft aan welke STL-headerbestanden kunnen worden gecompileerd tot header units. Een koptekst die afhankelijk is van macro's om het gedrag ervan op te geven, kan vaak niet worden gecompileerd in een kopteksteenheid.

Een #include verklaring die niet naar een header-eenheid verwijst, wordt behandeld als een normale #include.

Headerunits hergebruiken tussen projecten

Header-eenheden die zijn gebouwd door een statisch bibliotheekproject, zijn automatisch beschikbaar voor alle projecten die er direct of indirect naar verwijzen. Er zijn projectinstellingen waarmee u kunt selecteren welke header-eenheden automatisch beschikbaar moeten zijn voor alle projecten die naar dit project verwijzen. De instellingen bevinden zich in projectinstellingen onder VC++-mappen.

  1. Klik in Solution Explorer met de rechtermuisknop op het project en selecteer Eigenschappen om het dialoogvenster Eigenschappenpagina's van het project te openen.
  2. Selecteer in het linkerdeelvenster van het dialoogvenster CONFIGURATIE-eigenschappen>VC++-mappen: Schermopname van eigenschappen van openbare projectinhoud, zoals Openbare inclusief mappen en Alle headerbestanden zijn openbaar.

De volgende eigenschappen bepalen de zichtbaarheid van header-eenheden voor het buildsysteem:

  • Public Include Directories specificeert projectmappen voor header-units die automatisch moeten worden opgenomen in de include-paden van verwijzende projecten.
  • Openbare C++-modulemappen specificeren welke projectmappen kopteksteenheden bevatten die beschikbaar moeten zijn om te verwijzen naar projecten. Met deze eigenschap kunt u enkele header-eenheden openbaar maken. Het is zichtbaar voor andere projecten, dus plaats hier de koptekst-eenheden die u wilt delen. Als u deze instelling gebruikt, specificeer voor het gemak Publieke Include-mappen om uw openbare headers automatisch toe te voegen aan het Include-pad in verwijzende projecten.
  • Alle modules zijn openbaar: wanneer u header-eenheden gebruikt die zijn gebouwd als onderdeel van een DLL-project, moeten de symbolen worden geëxporteerd uit het DLL-bestand. Als u modulesymbolen automatisch wilt exporteren, stelt u deze eigenschap in op Ja.

Een vooraf samengesteld modulebestand gebruiken

De eenvoudigste manier om header-eenheden tussen oplossingen opnieuw te gebruiken, is meestal door vanuit elke oplossing te verwijzen naar een project voor een gedeelde headereenheid.

Als u een ingebouwde header-eenheid moet gebruiken waarvoor u het project niet hebt, kunt u opgeven waar het ingebouwde .ifc bestand zich bevindt, zodat u het in uw oplossing kunt importeren. Ga als volgt te werk om toegang te krijgen tot deze instelling:

  1. Selecteer inhet hoofdmenu> om het dialoogvenster Projecteigenschappenpagina's te openen.
  2. Selecteer in het linkerdeelvenster van het dialoogvenster Configuratie-eigenschappen>C/C++>Algemeen.
  3. Voeg in Aanvullende moduleafhankelijkheden de modules toe waarnaar moet worden verwezen, gescheiden door puntkomma's. Hier volgt een voorbeeld van de indeling die moet worden gebruikt voor Aanvullende moduleafhankelijkheden: ModuleName1=Path\To\ModuleName1.ifc; ModuleName2=Path\To\ModuleName2.ifcSchermopname van eigenschappen van projecteigenschappen onder Configuratie-eigenschappen, C/C++, Algemeen, met Aanvullende moduleafhankelijkheden geselecteerd.

Kies tussen meerdere exemplaren van een koptekst eenheid

Als u verwijst naar projecten die meerdere header-eenheden maken, met dezelfde naam of voor hetzelfde headerbestand, moet u opgeven welke moet worden gebruikt. Mogelijk hebt u verschillende versies van de header-eenheid die is gebouwd met verschillende compilerinstellingen, en moet u bijvoorbeeld de eenheid opgeven die overeenkomt met uw projectinstellingen.

Gebruik de eigenschap Extra header-eenheidsafhankelijkheden van het project om conflicten op te lossen door op te geven welke headereenheid moet worden gebruikt. Anders is het niet mogelijk om te voorspellen welke wordt gekozen.

De eigenschap Extra Header-eenheidsafhankelijkheden instellen:

  1. Selecteer inhet hoofdmenu> om het dialoogvenster Projecteigenschappenpagina's te openen.
  2. Selecteer in het linkerdeelvenster van het dialoogvenster Configuratie-eigenschappen>C/C++>Algemeen.
  3. Geef op welke modules of headerveldbestanden moeten worden gebruikt in aanvullende headereenheidafhankelijkheden om conflicten op te lossen. Gebruik dit format voor Extra Header Unit Dependencies: Path\To\Header1.h= Path\To\HeaderUnit1.ifc;Path\To\Header2.h= Path\To\ HeaderUnit2.ifcSchermafbeelding die de Extra Headereenheidafhankelijkheden instelling in het eigenschappenpagina dialoogvenster van het project toont.

Belangrijk

Zorg ervoor dat projecten die header-eenheden delen, zijn gebouwd met compatibele compilatieopties. Als u compilatieopties gebruikt wanneer u de header-eenheid implementeert die afwijken van de eenheden die u hebt gebruikt toen u deze hebt gemaakt, geeft de compiler waarschuwingen.

Opmerking

Als u kopteksteenheden wilt gebruiken die zijn gebouwd als onderdeel van een DLL-project, stelt u Alle modules zijn openbaar op Ja.

Benadering 2: Scan omvat voor STL-headers die moeten worden geïmporteerd

Een andere manier om STL-bibliotheken te importeren, is door Visual Studio te laten scannen op de STL-headers die u #include in uw project hebt en deze samen te stellen in header-eenheden. De compiler importeert die headers in plaats van ze te includeren.

Deze optie is handig wanneer uw project veel STL-headerbestanden bevat in veel bestanden of wanneer de builddoorvoer niet kritiek is. Met deze optie wordt niet gegarandeerd dat een header-eenheid voor een bepaald headerbestand slechts één keer wordt gemaakt. Het is echter handig als u een grote codebasis hebt: u hoeft uw broncode niet te wijzigen om te profiteren van de voordelen van header-eenheden voor veel van de STL-bibliotheken die u gebruikt.

Deze benadering is minder flexibel dan de statische bibliotheekbenadering, omdat deze zich niet leent voor het hergebruik van de ingebouwde header-eenheden in andere projecten. Deze benadering is mogelijk niet geschikt voor grotere projecten: het garandeert geen optimale buildtijd, omdat alle bronnen moeten worden gescand op #include instructies.

Niet alle headerbestanden kunnen automatisch worden geconverteerd naar header-eenheden. Kopteksten die afhankelijk zijn van voorwaardelijke compilatie via macro's, moeten bijvoorbeeld niet geconverteerd worden naar eenheden voor kopteksten. Er is een acceptatielijst in de vorm van een header-units.json bestand voor de STL-headers die door de compiler worden gebruikt wanneer /translateInclude deze is opgegeven. Hiermee wordt bepaald welke STL-headerbestanden tot headereenheden kunnen worden gecompileerd. Het header-units.json bestand bevindt zich onder de installatiemap voor Visual Studio. Bijvoorbeeld: %ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json. Als het STL-headerbestand zich niet in de lijst bevindt, wordt het beschouwd als een normaal #include bestand in plaats van het te importeren als een kopteksteenheid. Een ander voordeel van het header-units.json bestand is dat symboolduplicatie in de ingebouwde headereenheden wordt voorkomen. Als het compileren van een kopteksteenheid meerdere keren een andere bibliotheekkoptekst oplevert, worden de symbolen dus niet gedupliceerd.

Als u deze aanpak wilt uitproberen, maakt u een project met twee STL-bibliotheken. Wijzig vervolgens de eigenschappen van het project zodat de bibliotheken als header-eenheden worden geïmporteerd in plaats van ze in te sluiten, zoals beschreven in de volgende sectie.

Een C++-console-app-project maken

Volg deze stappen om een project te maken dat twee STL-bibliotheken bevat: <iostream> en <vector>.

  1. Maak in Visual Studio een nieuw C++-console-app-project.

  2. Vervang de inhoud van het bronbestand als volgt:

    #include <iostream>
    #include <vector>
    
    int main()
    {
        std::vector<int> numbers = {0, 1, 2};
        std::cout << numbers[1];
    }
    

Projectopties instellen en het project uitvoeren

Met de volgende stappen stelt u de optie in die ervoor zorgt dat de compiler scant op opgenomen headers om te zetten in headereenheden. Ze stellen ook de optie in die ervoor zorgt dat de compiler #include behandelt alsof u import hebt geschreven voor headerbestanden die als header-eenheden kunnen worden behandeld.

  1. Selecteer inhet hoofdmenu> om het dialoogvenster Projecteigenschappenpagina's te openen.
  2. Selecteer Alle configuraties in de vervolgkeuzelijst Configuratie en selecteer vervolgens Alle platforms in de vervolgkeuzelijst Platform . Deze instellingen zorgen ervoor dat uw wijzigingen van toepassing zijn, ongeacht of u bouwt voor foutopsporing of release en andere configuraties.
  3. Selecteer in het linkerdeelvenster van het dialoogvenster Configuratie-eigenschappen>C/C++>Algemeen.
  4. Stel Scanbronnen voor moduleafhankelijkheden in op Ja. Deze instelling zorgt ervoor dat alle compatibele headerbestanden worden gecompileerd in headereenheden.
  5. Stel Inclusies vertalen naar Importen in op Ja. Met deze instelling worden de STL-headerbestanden gecompileerd die in het header-unit.json bestand als headereenheden worden vermeld en worden ze vervolgens geïmporteerd in plaats van de preprocessor ernaar te #include gebruiken. Schermopname van de eigenschapsinstelling voor scanmoduleafhankelijkheden in de projecteigenschapspagina's.
  6. Kies OK om uw wijzigingen op te slaan en het dialoogvenster Eigenschappenpagina's van het project te sluiten.

De /std:c++20 optie of hoger is vereist voor het gebruik van koptekst-eenheden. De C++-taalstandaard wijzigen die wordt gebruikt door de compiler:

  1. Selecteer inhet hoofdmenu> om het dialoogvenster Projecteigenschappenpagina's te openen.
  2. Selecteer Alle configuraties in de vervolgkeuzelijst Configuratie en selecteer vervolgens Alle platforms in de vervolgkeuzelijst Platform . Deze instellingen zorgen ervoor dat uw wijzigingen van toepassing zijn, ongeacht of u bouwt voor foutopsporing of release en andere configuraties.
  3. Selecteer in het linkerdeelvenster van het dialoogvenster Eigenschappenpagina's van het project de optie Configuratie-eigenschappen>algemeen.
  4. Selecteer in de vervolgkeuzelijst C++ Language StandardISO C++20 Standard (/std:c++20) (of hoger).
  5. Kies OK om uw wijzigingen op te slaan en het dialoogvenster Eigenschappenpagina's van het project te sluiten.
  6. In het hoofdmenu bouwt u de oplossing door Build>Build Solution te selecteren.

Voer de oplossing uit om te controleren of deze de verwachte uitvoer produceert: 1

De belangrijkste overweging voor het gebruik van deze benadering is de balans tussen gemak en de kosten voor het scannen van al uw bestanden om te bepalen welke headerbestanden moeten worden gebouwd als headereenheden.

Zie ook

Header-eenheden, modules en voorgecompileerde headers vergelijken
Zelfstudie: De standaardbibliotheek van C++ importeren met behulp van modules
Handleiding: Header-eenheden bouwen en importeren in uw Microsoft C++-projecten
/translateInclude