Question

Quels sont les avantages d'une bibliothèque d'en-tête uniquement et pourquoi l'écrivez-vous de cette façon au lieu de mettre l'implémentation dans un fichier séparé ?

Était-ce utile?

La solution

Il existe des situations où une bibliothèque contenant uniquement des en-têtes est la seule option, par exemple lorsqu'il s'agit de modèles.

Avoir une bibliothèque contenant uniquement des en-têtes signifie également que vous n'avez pas à vous soucier des différentes plates-formes sur lesquelles la bibliothèque peut être utilisée.Lorsque vous séparez l'implémentation, vous le faites généralement pour masquer les détails de l'implémentation et distribuer la bibliothèque sous la forme d'une combinaison d'en-têtes et de bibliothèques (lib, dllou .so des dossiers).Ceux-ci doivent bien sûr être compilés pour tous les différents systèmes d’exploitation/versions que vous proposez.

Vous pouvez également distribuer les fichiers d'implémentation, mais cela signifierait une étape supplémentaire pour l'utilisateur : compiler votre bibliothèque avant de l'utiliser.

Bien sûr, cela s'applique à un cas par cas base.Par exemple, les bibliothèques d'en-tête uniquement augmentent parfois taille du code & temps de compilation.

Autres conseils

Avantages de la bibliothèque d'en-tête uniquement:

  • simplifie le processus de construction. Vous n'avez pas besoin de construire la bibliothèque et vous n'avez pas besoin de spécifier la bibliothèque compilée pendant l'étape de lien de la construction. Si vous avez une bibliothèque compilée, vous voudrez probablement créer plusieurs versions de celui-ci: une compilée avec le débogage activé, une autre avec optimisation activée et éventuellement une autre dépouillée de symboles. Et peut-être encore plus pour un système multi-plateformes.

    Inconvénients d'une bibliothèque d'en-tête uniquement:

    • Fichiers d'objet plus gros. Chaque méthode inline à partir de la bibliothèque utilisée dans certains fichiers sources obtiendra également un symbole faible, définition hors ligne dans le fichier d'objet compilé pour ce fichier source. Cela ralentit le compilateur et ralentit également la liaison. Le compilateur doit générer tout ce gonflement, puis la lieur doit le filtrer.

    • compilation plus longue. En plus du problème de gonflement mentionné ci-dessus, la compilation prendra plus de temps car les en-têtes sont intrinsèquement plus importants avec une bibliothèque d'en-tête uniquement qu'une bibliothèque compilée. Ces gros en-têtes devront être analysés pour chaque fichier source utilisant la bibliothèque. Un autre facteur est que ces fichiers d'en-tête d'une bibliothèque d'en-tête uniquement doivent généracoDiCodeTagcode les en-têtes nécessaires aux définitions en ligne, ainsi que par les en-têtes nécessaires, si la bibliothèque a été construite comme une bibliothèque compilée.

    • compilation plus enchevêtrée. Vous obtenez beaucoup plus de dépendances avec une bibliothèque d'en-tête uniquement en raison de ces excréments de généracoDiCodes supplémentaires nécessaires à une bibliothèque d'en-tête uniquement. Modifiez la mise en œuvre d'une fonction clé de la bibliothèque et vous aurez peut-être bien besoin de recompiler l'ensemble du projet. Faites de cette modification dans le fichier source d'une bibliothèque compilée et tout ce que vous avez à faire est de recompiler qu'un fichier source de bibliothèque, mettez à jour la bibliothèque compilée avec ce nouveau fichier .O et que vous désirez l'application.

    • plus difficile pour l'homme de lire. Même avec la meilleure documentation, les utilisateurs d'une bibliothèque de plusieurs fois doivent avoir recours à la lecture des en-têtes de la bibliothèque. Les en-têtes d'une bibliothèque d'en-tête seulement sont remplis de détails de mise en œuvre qui mettent en œuvre l'interface. Avec une bibliothèque compilée, tout ce que vous voyez est l'interface et un bref commentaire sur la mise en œuvre de la mise en œuvre, et c'est généralement tout ce que vous voulez. C'est vraiment tout ce que vous devriez vouloir. Vous ne devriez pas avoir à connaître les détails de la mise en œuvre pour savoir comment utiliser la bibliothèque.

Je sais que c'est un vieux fil, mais personne n'a mentionné des interfaces ABI ou des problèmes spécifiques du compilateur. Alors je pensais que je voudrais.

Ceci est essentiellement basé sur le concept de vous écrivez une bibliothèque avec un en-tête pour vous distribuer aux personnes ou réutilisez-vous que vous avez tout dans une en-tête. Si vous envisagez de réutiliser un chiffre d'en-tête et des fichiers source et de les recompiler dans chaque projet, cela ne s'applique pas vraiment.

Fondamentalement, si vous compilez votre code C ++ et créez une bibliothèque avec un compilateur, l'utilisateur tente d'utiliser cette bibliothèque avec un autre compilateur ou une version différente du même compilateur, vous pouvez obtenir des erreurs de liaison ou un comportement d'exécution étrange en raison de Incompatibilité.

Par exemple, les fournisseurs de compilation modifient souvent leur mise en œuvre de la STL entre les versions. Si vous avez une fonction dans une bibliothèque qui accepte un STD :: vecteur, il s'attend à ce que les octets de cette catégorie soient arrangés de la manière dont ils ont été arrangés lorsque la bibliothèque a été compilée. Si, dans une nouvelle version du compilateur, le fournisseur a apporté une amélioration de l'efficacité à STD :: Vector, alors le code de l'utilisateur voit la nouvelle classe qui peut avoir une structure différente et transmet cette nouvelle structure dans votre bibliothèque. Tout se passe en descente de là ... C'est pourquoi il est recommandé de ne pas transmettre des objets STL à travers les limites de la bibliothèque. La même chose s'applique aux types de temps d'exécution C (CRT).

En parlant de la CRT, votre bibliothèque et le code source de l'utilisateur doivent généralement être liés contre le même CRT. Avec Visual Studio Si vous construisez votre bibliothèque à l'aide du CRT multithreaded, mais que l'utilisateur est lié à la CRT de débogage multithread, alors vous aurez des problèmes de liaison car votre bibliothèque peut ne pas trouver les symboles dont il a besoin. Je ne me souviens pas de quelle fonction c'était la fonction, mais pour Visual Studio 2015, Microsoft a créé une fonction CRT en ligne. Soudain, c'était dans l'en-tête, pas la bibliothèque CRT, donc les bibliothèques qui s'attendaient à la trouver au moment de la liaison ne pouvaient plus faire et ces erreurs de liaison générées. Le résultat était que ces bibliothèques ont besoin de recompiler avec Visual Studio 2015.

Vous pouvez également obtenir des erreurs de liaison ou un comportement étrange si vous utilisez l'API Windows, mais vous construisez avec différents paramètres Unicode à l'utilisateur de la bibliothèque. En effet, l'API Windows a des fonctions qui utilisent des chaînes UNICODE ou ASCII et des macros / définitions qui utilisent automatiquement les types correct basés sur les paramètres Unicode du projet. Si vous passez une chaîne sur la limite de la bibliothèque qui est le mauvais type, les choses se cassent au moment de l'exécution. Ou vous pouvez constater que le programme ne lie pas en premier lieu.

Ces choses sont également vraies pour passer des objets / types de la bibliothèque à partir d'autres bibliothèques tierces (par exemple, un vecteur Eigen ou une matrice GSL). Si la bibliothèque tierce change son en-tête entre vous compilez votre bibliothèque et que votre utilisateur compilait son code, les choses vont se briser.

Fondamentalement pour être en sécurité, les seules choses que vous pouvez transmettre à travers les limites de la bibliothèque sont intégrées à des types et de données anciennes (POD). Idéalement, tout POD devrait être dans les structures définies dans vos propres en-têtes et ne repose pas sur des en-têtes tiers.

Si vous fournissez une en-tête uniquement la bibliothèque, tout le code est compilé avec les mêmes paramètres du compilateur et par rapport aux mêmes en-têtes de sorte que beaucoup de ces problèmes disparaissent (fournissant la version de troisième partiellement des bibliothèques que vous utilisez et que votre utilisateur utilise est une API compatible. ).

Cependant, il existe des négatifs mentionnés ci-dessus, tels que l'augmentation du temps de compilation. Vous pouvez également exécuter une entreprise afin que vous ne souhaitiez peut-être pas de remettre tous vos informations de mise en œuvre de votre code source à tous vos utilisateurs au cas où l'un d'entre eux le voler.

Le principal "avantage" est qu'il vous oblige à livrer un code source, donc vous vous retrouverez avec des rapports d'erreur sur des machines et avec des compilateurs que vous avez jamais entendu parler de.Lorsque la bibliothèque est entièrement des modèles, vous n'avez pas beaucoup de choix, mais quand vous avez le choix, l'en-tête est généralement un pauvre choix d'ingénierie.(D'autre part, bien sûr, l'en-tête signifie seulement que Vous n'avez pas à documenter une procédure d'intégration.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top