Partager via


Procédure pas à pas : Importer des bibliothèques STL en tant qu’unités d’en-tête

Cette procédure pas à pas montre comment importer des bibliothèques STL (Standard Template Library) C++ en tant qu’unités d’en-tête dans Visual Studio. Pour obtenir un moyen encore plus rapide et plus robuste d’importer la bibliothèque standard, consultez Tutoriel : Importer la bibliothèque standard C++ à l’aide de modules.

L’importation d’un en-tête STL en tant qu’unité d’en-tête est plus simple que d’utiliser des fichiers d’en-tête précompilés. Les unités d’en-tête sont plus faciles à configurer et à utiliser, sont sensiblement plus petites sur le disque, offrent des avantages similaires aux performances et sont plus flexibles qu’un PCH partagé.

Pour plus d’informations sur les unités d’en-tête et les avantages qu’ils fournissent, consultez Qu’est-ce qu’une unité d’en-tête ?. Pour comparer les unités d’en-tête avec d’autres façons d’importer la bibliothèque standard, consultez Comparer les unités d’en-tête, les modules et les en-têtes précompilés.

Prérequis

Pour utiliser des unités d’en-tête, utilisez Visual Studio 2022 ou version ultérieure, ou Visual Studio 2019 version 16.11 ou ultérieure. L’option /std:c++20 (ou une version ultérieure) est nécessaire pour utiliser des unités d’en-tête.

Deux approches pour importer des en-têtes STL en tant qu’unités d’en-tête

Avant de pouvoir importer un en-tête STL, il doit être compilé dans une unité d’en-tête. Une unité d’en-tête est une représentation binaire d’un fichier d’en-tête. Il a une .ifc extension.

L’approche recommandée consiste à créer une bibliothèque statique qui contient les unités d’en-tête générées pour les en-têtes STL que vous souhaitez utiliser. Référencez ensuite cette bibliothèque et import ses unités d’en-tête. Cette approche peut entraîner des builds plus rapides et une meilleure réutilisation. Pour tester cette approche, consultez l’approche 1 : Créer une bibliothèque statique d’unités d’en-tête de bibliothèque STL.

Une autre approche consiste à rechercher les en-têtes STL que vous #include avez dans votre projet, à les compiler en unités d’en-tête et import non à #include ces en-têtes. Cette approche est utile si vous avez une base de code volumineuse, car vous n’avez pas à modifier votre code source. Cette approche est moins flexible que l’approche de bibliothèque statique, car elle ne se prête pas à réutiliser les unités d’en-tête générées dans d’autres projets. Toutefois, vous bénéficiez toujours de l’avantage de l’importation de bibliothèques STL individuelles en tant qu’unités d’en-tête. Pour tester cette approche, consultez l’approche 2 : l’analyse inclut les en-têtes STL à importer.

Approche 1 : Créer une bibliothèque statique d’unités d’en-tête de bibliothèque STL

La méthode recommandée pour consommer des bibliothèques STL en tant qu’unités d’en-tête consiste à créer un ou plusieurs projets de bibliothèque statique. Ces projets doivent se composer des unités d’en-tête de bibliothèque STL que vous souhaitez utiliser. Ensuite, référencez les projets de bibliothèque pour consommer ces unités d’en-tête STL. Il est similaire à l’utilisation d’en-têtes précompilés partagés, mais plus facile.

Les unités d’en-tête (et modules) intégrées à un projet de bibliothèque statique sont automatiquement disponibles pour référencer des projets, car le système de projet ajoute automatiquement l’option de ligne de commande appropriée /headerUnit au compilateur afin que les projets de référence puissent importer les unités d’en-tête.

Cette approche garantit que l’unité d’en-tête d’un en-tête particulier n’est générée qu’une seule fois. Il vous permet d’importer une partie ou l’ensemble des unités d’en-tête, ce qui n’est pas possible avec un PCH. Vous pouvez inclure des unités d’en-tête dans n’importe quel ordre.

Dans l’exemple suivant, vous créez un projet de bibliothèque statique composé des unités d’en-tête et <vector> de l’en-tête<iostream>. Une fois la solution générée, vous allez référencer ce projet d’unité d’en-tête partagée à partir d’un autre projet C++. import <iostream>; Partout ou import <vector>; trouvé, l’unité d’en-tête générée pour cette bibliothèque est utilisée au lieu de traduire l’en-tête avec le préprocesseur. Il améliore les performances de build, comme les fichiers PCH, lorsque le même en-tête est inclus dans plusieurs fichiers. L’en-tête n’a pas besoin d’être traité par les fichiers qui l’incluent. Au lieu de cela, l’unité d’en-tête compilée déjà traitée est importée.

Pour créer une bibliothèque statique qui contient les bibliothèques <iostream> STL et <vector>procédez comme suit :

  1. Créez un projet C++ vide. Nommez-le SharedPrj.
    Sélectionnez Projet vide pour C++ dans les types de projet disponibles dans la fenêtre Créer un projet : Screenshot that shows creating a new empty C++ project.

  2. Ajoutez un nouveau fichier C++ au projet. Remplacez le contenu du fichier par :

    import <iostream>;
    import <vector>;
    

Définir les propriétés du projet

Définissez les propriétés du projet pour partager les unités d’en-tête de ce projet :

  1. Dans le menu principal de Visual Studio, sélectionnez Propriétés du projet>SharedPrj pour ouvrir la boîte de dialogue Pages de propriétés du projet :Screenshot that shows settings for Configuration Type and C++ Language Standard.
  2. Sélectionnez Toutes les configurations dans la liste déroulante Configuration , puis sélectionnez Toutes les plateformes dans la liste déroulante Plateforme . Ces paramètres garantissent que vos modifications s’appliquent si vous générez pour le débogage ou la mise en production.
  3. Dans le volet gauche de la boîte de dialogue Pages de propriétés du projet, sélectionnez Propriétés>générales de configuration.
  4. Modifiez l’option Type de configuration en bibliothèque statique (.lib).
  5. Remplacez C++ Language Standard par ISO C++20 Standard (/std :c++20) (ou version ultérieure).
  6. Dans le volet gauche de la boîte de dialogue Pages de propriétés du projet, sélectionnez Propriétés>de configuration C/C++>Général.
  7. Dans la liste déroulante Rechercher des dépendances de module, sélectionnez Oui. (Cette option entraîne l’analyse de votre code par le compilateur pour les dépendances qui peuvent être intégrées aux unités d’en-tête) : Screenshot that shows the scan module dependencies property setting.
  8. Choisissez OK pour fermer la boîte de dialogue Pages de propriétés du projet. Générez la solution en sélectionnant Générer>la solution dans le menu principal.

Référencer la bibliothèque d’unités d’en-tête

Pour importer <iostream> et <vector> en tant qu’unités d’en-tête à partir de la bibliothèque statique, créez un projet qui référence la bibliothèque statique comme suit :

  1. Lorsque la solution actuelle est toujours ouverte, dans le menu Visual Studio, sélectionnez Ajouter>>un nouveau projet.

  2. Dans l’Assistant Création d’un projet, sélectionnez le modèle d’application console C++ et choisissez Suivant.

  3. Nommez la nouvelle procédure pas à pas du projet. Modifiez la liste déroulante Solution pour ajouter à la solution. Choisissez Créer pour créer le projet et l’ajouter à votre solution.

  4. Modifiez le contenu du fichier source Walkthrough.cpp comme suit :

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

Les unités d’en-tête nécessitent l’option /std:c++20 (ou une version ultérieure). Définissez la norme linguistique en procédant comme suit :

  1. Dans Explorateur de solutions, cliquez avec le bouton droit sur le projet pas à pas et sélectionnez Propriétés pour ouvrir la boîte de dialogue Pages de propriétés du projet :Screenshot that shows setting the language standard to the preview version.
  2. Dans le volet gauche de la boîte de dialogue Pages de propriétés du projet de procédure pas à pas, sélectionnez Propriétés>générales de configuration.
  3. Dans la liste déroulante C++ Language Standard , sélectionnez ISO C++20 Standard (/std :c++20) (ou version ultérieure).
  4. Choisissez OK pour fermer la boîte de dialogue Pages de propriétés du projet.

Dans le projet de procédure pas à pas , ajoutez une référence au projet SharedPrj en procédant comme suit :

  1. Dans le projet de procédure pas à pas , sélectionnez le nœud Références , puis ajoutez une référence. Sélectionnez SharedPrj dans la liste des projets : Screenshot that shows the Add Reference dialog. It's used to add a reference to the Walkthrough project.L’ajout de cette référence entraîne l’utilisation des unités d’en-tête générées par SharedPrj chaque fois qu’un import projet de procédure pas à pas correspond à l’une des unités d’en-tête générées dans SharedPrj.
  2. Choisissez OK pour fermer la boîte de dialogue Ajouter une référence .
  3. Cliquez avec le bouton droit sur le projet de procédure pas à pas , puis sélectionnez Définir comme projet de démarrage.
  4. Générez la solution. (Utiliser Générer une solution de>génération dans le menu principal.) Exécutez-la pour voir qu’elle produit la sortie attendue :1

L’avantage de cette approche est que vous pouvez référencer le projet de bibliothèque statique à partir de n’importe quel projet pour réutiliser les unités d’en-tête dans celui-ci. Dans cet exemple, la bibliothèque statique contient les unités d’en-tête et <iostream> les <vector> unités d’en-tête.

Vous pouvez créer un projet de bibliothèque statique monolithique qui contient tous les en-têtes STL couramment utilisés que vous souhaitez importer à partir de vos différents projets. Vous pouvez également créer des projets de bibliothèque partagée plus petits pour les différents regroupements de bibliothèques STL que vous souhaitez importer en tant qu’unités d’en-tête. Référencez ensuite ces projets d’unité d’en-tête partagée en fonction des besoins.

Le résultat doit être augmenté de débit de build, car l’importation d’une unité d’en-tête réduit considérablement le travail que le compilateur doit effectuer.

Lorsque vous utilisez cette approche avec vos propres projets, générez le projet de bibliothèque statique avec des options de compilateur compatibles avec le projet qui le référence. Par exemple, les projets STL doivent être générés avec l’option du compilateur pour activer la /EHsc gestion des exceptions, et les projets qui référencent le projet de bibliothèque statique doivent donc être activés.

Utilisez /translateInclude.

L’option /translateInclude du compilateur (disponible dans la boîte de dialogue Pages de propriétés du projet sous C/C++>General>Translate Includes to Imports) facilite l’utilisation d’une bibliothèque d’unités d’en-tête dans les projets plus anciens que #include les bibliothèques STL. Il n’est pas nécessaire de modifier #include les directives dans import votre projet, tout en vous donnant l’avantage d’importer les unités d’en-tête au lieu de les inclure.

Par exemple, si vous avez #include <vector> dans votre projet et que vous référencez une bibliothèque statique qui contient une unité d’en-tête pour <vector>, vous n’avez pas besoin de passer #include <vector> manuellement à import <vector>; votre code source. Au lieu de cela, le compilateur traite #include <vector> automatiquement comme import <vector>;. Pour plus d’informations sur cette approche, consultez l’approche 2 : Analyse inclut les en-têtes STL à importer. Tous les fichiers d’en-tête STL ne peuvent pas être compilés dans une unité d’en-tête. Fourni header-units.json avec Visual Studio répertorie les fichiers d’en-tête STL pouvant être compilés en unités d’en-tête. Un en-tête qui s’appuie sur des macros pour spécifier son comportement ne peut souvent pas être compilé dans une unité d’en-tête.

Une #include instruction qui ne fait pas référence à une unité d’en-tête est traitée comme une instruction normale #include.

Réutiliser des unités d’en-tête parmi les projets

Les unités d’en-tête générées par un projet de bibliothèque statique sont automatiquement disponibles pour tous les projets directement et indirectement référençant. Il existe des paramètres de projet qui vous permettent de sélectionner les unités d’en-tête qui doivent être automatiquement disponibles pour tous les projets de référencement. Les paramètres se trouvent dans les paramètres du projet sous Répertoires VC++.

  1. Dans Explorateur de solutions, cliquez avec le bouton droit sur le projet et sélectionnez Propriétés pour ouvrir la boîte de dialogue Pages de propriétés du projet.
  2. Dans le volet gauche de la boîte de dialogue, sélectionnez Répertoires VC++ Propriétés>de configuration :Screenshot that shows public project content properties, like Public Include Directories and All Header Files are Public.

Les propriétés suivantes contrôlent la visibilité des unités d’en-tête sur le système de génération :

  • Public Include Directories spécifie les répertoires de projet pour les unités d’en-tête qui doivent être automatiquement ajoutées au chemin d’accès include dans le référencement de projets.
  • Les répertoires de module C++ publics spécifient les répertoires de projet qui contiennent des unités d’en-tête qui doivent être disponibles pour référencer des projets. Cette propriété vous permet de rendre certaines unités d’en-tête publiques. Il est visible par d’autres projets, donc placez les unités d’en-tête que vous souhaitez partager ici. Si vous utilisez ce paramètre, pour plus de commodité, spécifiez les répertoires Include publics pour ajouter automatiquement vos en-têtes publics au chemin Include dans le référencement de projets.
  • Tous les modules sont publics : lorsque vous utilisez des unités d’en-tête générées dans le cadre d’un projet DLL, les symboles doivent être exportés à partir de la DLL. Pour exporter automatiquement des symboles de module, définissez cette propriété sur Oui.

Utiliser un fichier de module prédéfini

En règle générale, le moyen le plus simple de réutiliser les unités d’en-tête parmi les solutions consiste à référencer un projet d’unité d’en-tête partagé de chaque solution.

Si vous devez utiliser une unité d’en-tête générée pour laquelle vous n’avez pas le projet, vous pouvez spécifier l’emplacement où se trouve le fichier généré .ifc afin de pouvoir l’importer dans votre solution. Pour accéder à ce paramètre :

  1. Dans le menu principal, sélectionnez >Propriétés du projet pour ouvrir la boîte de dialogue Pages de propriétés du projet.
  2. Dans le volet gauche de la boîte de dialogue, sélectionnez Propriétés>de configuration C/C++>Général.
  3. Dans Les dépendances de module supplémentaires, ajoutez les modules à référencer, séparés par des points-virgules. Voici un exemple de format à utiliser pour les dépendances de module supplémentaires : ModuleName1=Path\To\ModuleName1.ifc; ModuleName2=Path\To\ModuleName2.ifcScreenshot showing project Property Pages properties under Configuration Properties, C/C++, General, with Additional Module Dependencies selected.

Sélectionner parmi plusieurs copies d’une unité d’en-tête

Si vous référencez des projets qui créent plusieurs unités d’en-tête, avec le même nom ou pour le même fichier d’en-tête, vous devez spécifier celui à utiliser. Vous disposez peut-être de différentes versions de l’unité d’en-tête créées avec différents paramètres du compilateur, par exemple, et devez spécifier celle qui correspond aux paramètres de votre projet.

Utilisez la propriété Dépendances de l’unité d’en-tête supplémentaire du projet pour résoudre les collisions en spécifiant l’unité d’en-tête à utiliser. Sinon, il n’est pas possible de prédire celui qui est choisi.

Pour définir la propriété Dépendances de l’unité d’en-tête supplémentaire :

  1. Dans le menu principal, sélectionnez >Propriétés du projet pour ouvrir la boîte de dialogue Pages de propriétés du projet.
  2. Dans le volet gauche de la boîte de dialogue, sélectionnez Propriétés>de configuration C/C++>Général.
  3. Spécifiez les modules ou les fichiers d’unité d’en-tête à utiliser dans des dépendances d’unité d’en-tête supplémentaires pour résoudre les collisions. Utilisez ce format pour les dépendances d’unité d’en-tête supplémentaires : Path\To\Header1.h= Path\To\HeaderUnit1.ifc;Path\To\Header2.h= Path\To\ HeaderUnit2.ifcScreenshot that shows the Additional Header Unit Dependencies setting in the project Property Pages dialog.

Important

Vérifiez que les projets qui partagent des unités d’en-tête sont générés avec des options de compilation compatibles. Si vous utilisez des options de compilation lorsque vous implémentez l’unité d’en-tête différente de celle que vous avez utilisée lors de sa création, le compilateur émet des avertissements.

Remarque

Pour utiliser les unités d’en-tête générées dans le cadre d’un projet DLL, définissez Tous les modules sur Oui.

Approche 2 : l’analyse inclut les en-têtes STL à importer

Une autre façon d’importer des bibliothèques STL consiste à rechercher les en-têtes STL que vous #include avez dans votre projet et à les compiler en unités d’en-tête. Le compilateur importe ensuite plutôt que d’inclure ces en-têtes.

Cette option est pratique lorsque votre projet inclut de nombreux fichiers d’en-tête STL sur de nombreux fichiers, ou lorsque le débit de build n’est pas critique. Cette option ne garantit pas qu’une unité d’en-tête pour un fichier d’en-tête particulier n’est générée qu’une seule fois. Toutefois, il est utile si vous avez une base de code volumineuse : vous n’avez pas besoin de modifier votre code source pour tirer parti des avantages des unités d’en-tête pour la plupart des bibliothèques STL que vous utilisez.

Cette approche est moins flexible que l’approche de la bibliothèque statique, car elle ne se prête pas à réutiliser les unités d’en-tête générées dans d’autres projets. Cette approche peut ne pas convenir à des projets plus volumineux : elle ne garantit pas un temps de génération optimal, car toutes les sources doivent être analysées pour les #include instructions.

Tous les fichiers d’en-tête ne peuvent pas être automatiquement convertis en unités d’en-tête. Par exemple, les en-têtes qui dépendent de la compilation conditionnelle via des macros ne doivent pas être convertis en unités d’en-tête. Il existe une liste verte sous la forme d’un header-units.jsonfichier pour les en-têtes STL que le compilateur utilise lorsqu’il /translateInclude est spécifié. Il détermine quels en-têtes STL peuvent être compilés en unités d’en-tête. Le header-units.json fichier se trouve dans le répertoire d’installation de Visual Studio. Par exemple, %ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\include\header-units.json Si le fichier d’en-tête STL n’est pas dans la liste, il est traité comme normal #include au lieu de l’importer comme une unité d’en-tête. Un autre avantage du header-units.json fichier est qu’il empêche la duplication de symboles dans les unités d’en-tête générées. Autrement dit, si la compilation d’une unité d’en-tête apporte plusieurs fois un autre en-tête de bibliothèque, les symboles ne sont pas dupliqués.

Pour tester cette approche, créez un projet qui inclut deux bibliothèques STL. Ensuite, modifiez les propriétés du projet afin qu’elle importe les bibliothèques en tant qu’unités d’en-tête au lieu de les inclure, comme décrit dans la section suivante.

Créer un projet d’application console C++

Procédez comme suit pour créer un projet qui inclut deux bibliothèques STL : <iostream> et <vector>.

  1. Dans Visual Studio, créez un projet d’application console C++.

  2. Remplacez le contenu du fichier source comme suit :

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

Définir les options du projet et exécuter le projet

Les étapes suivantes définissent l’option qui amène le compilateur à analyser les en-têtes inclus à traduire en unités d’en-tête. Ils définissent également l’option qui amène le compilateur à traiter #include comme si vous aviez écrit import pour les fichiers d’en-tête qui peuvent être traités comme des unités d’en-tête.

  1. Dans le menu principal, sélectionnez >Propriétés du projet pour ouvrir la boîte de dialogue Pages de propriétés du projet.
  2. Sélectionnez Toutes les configurations dans la liste déroulante Configuration , puis sélectionnez Toutes les plateformes dans la liste déroulante Plateforme . Ces paramètres garantissent que vos modifications s’appliquent si vous créez pour le débogage ou la mise en production et d’autres configurations.
  3. Dans le volet gauche de la boîte de dialogue, sélectionnez Propriétés>de configuration C/C++>Général.
  4. Définissez oui les sources d’analyse pour les dépendances de module. Ce paramètre garantit que tous les fichiers d’en-tête compatibles sont compilés en unités d’en-tête.
  5. Définissez Translate Inclut en importations sur Oui. Ce paramètre compile les fichiers d’en-tête STL répertoriés dans le header-unit.json fichier en tant qu’unités d’en-tête, puis les importe au lieu d’utiliser le préprocesseur.#include Screenshot that shows the scan module dependencies property setting in the project Property Pages.
  6. Choisissez OK pour enregistrer vos modifications et fermer la boîte de dialogue Pages de propriétés du projet.

L’option /std:c++20 ou une version ultérieure est nécessaire pour utiliser des unités d’en-tête. Pour modifier la norme de langage C++ utilisée par le compilateur :

  1. Dans le menu principal, sélectionnez >Propriétés du projet pour ouvrir la boîte de dialogue Pages de propriétés du projet.
  2. Sélectionnez Toutes les configurations dans la liste déroulante Configuration , puis sélectionnez Toutes les plateformes dans la liste déroulante Plateforme . Ces paramètres garantissent que vos modifications s’appliquent si vous créez pour le débogage ou la mise en production et d’autres configurations.
  3. Dans le volet gauche de la boîte de dialogue Pages de propriétés du projet, sélectionnez Propriétés>générales de configuration.
  4. Dans la liste déroulante C++ Language Standard , sélectionnez ISO C++20 Standard (/std :c++20) (ou version ultérieure).
  5. Choisissez OK pour enregistrer vos modifications et fermer la boîte de dialogue Pages de propriétés du projet.
  6. Dans le menu principal, générez la solution en sélectionnant Générer>la solution.

Exécutez la solution pour vérifier qu’elle produit la sortie attendue : 1

La principale considération pour savoir si cette approche doit être utilisée est l’équilibre entre commodité et coût d’analyse de tous vos fichiers pour déterminer les fichiers d’en-tête à générer en tant qu’unités d’en-tête.

Voir aussi

Comparer les unités d’en-tête, les modules et les en-têtes précompilés
Tutoriel : Importer la bibliothèque standard C++ à l’aide de modules
Procédure pas à pas : Générer et importer des unités d’en-tête dans vos projets Visual C++
/translateInclude