375 votes

Différence entre les objets partagés (.so), les bibliothèques statiques (.une) et DLL ' s (.so) ?

J'ai été impliqué dans un débat à l'égard des bibliothèques dans Linux, et tiens à confirmer certaines choses.

Il est de ma compréhension (corrigez-moi si je me trompe et je vais modifier mon post plus tard), qu'il y a deux façons d'utiliser les bibliothèques lors de la construction d'une application:

  1. Les bibliothèques statiques (.un fichiers): Au moment de la liaison, une copie de l'ensemble de la bibliothèque est mise à la version finale de l'application, de sorte que les fonctions au sein de la bibliothèque sont toujours disponibles à la demande
  2. D'objets partagés.donc les fichiers): Au moment de la liaison, l'objet est vérifiée par rapport à son API via le correspondant de l'en-tête (.h) fichier. La bibliothèque n'est pas réellement utilisé jusqu'à l'exécution, où elle est nécessaire.

L'avantage évident des bibliothèques statiques, c'est qu'ils permettent à l'ensemble de l'application pour être autonome, tandis que le bénéfice des bibliothèques dynamiques, c'est que l' ".donc" fichier peut être remplacé (c'est à dire: dans le cas où il doit être mis à jour en raison d'un bogue de sécurité) sans nécessiter l'application de base pour être recompilé.

J'ai entendu certaines personnes font une distinction entre les objets partagés et les bibliothèques de liens dynamiques (DLL), même si elles sont à la fois ".de sorte que" les fichiers. Est-il une distinction entre les objets partagés et les Dll quand il s'agit de développement C/C++ sur Linux ou tout autre compatible POSIX OS (c'est à dire: MINIX, UNIX, QNX, etc)? Je me dit que la clé de la différence (pour l'instant), c'est que les objets partagés sont juste utilisés au moment de l'exécution, tandis que la DLL doit être ouvert à l'aide de la dlopen() appel à l'intérieur de l'application.

Enfin, j'ai également entendu certains développeurs mention "partagé archives", qui, à ma connaissance, sont également statiques des bibliothèques elles-mêmes, mais ne sont jamais utilisés par une application directement. Au lieu de cela, d'autres bibliothèques statiques permettra de relier contre le "partage des archives" de tirer certaines (mais pas toutes) des fonctions/ressources par le partage de l'archive dans la bibliothèque statique en cours de construction.

Je vous remercie tous d'avance pour votre aide.

Mise à jour:


Dans le contexte dans lequel ces termes sont fournies qu'à moi, je l'ai découvert les légères différences dans ces conditions, qui peut même être tout simplement des expressions familières dans mon secteur d'activité:

  1. L'Objet partagé: Une bibliothèque qui est automatiquement lié à un programme lorsque le programme démarre, et existe sous forme d'un fichier autonome. La bibliothèque est inclus dans le lien de la liste au moment de la compilation (c'est à dire: LDOPTS+=-lmylib pour un fichier de bibliothèque nommée mylib.donc)
  2. Statique de la Bibliothèque: Une bibliothèque qui est fusionné dans le programme lui-même au moment de la construction pour une seule (grande) de l'application contenant le code de l'application et le code de la bibliothèque qui est automatiquement lié à un programme lorsque le programme est construit, et la finale binaire contenant le programme principal et la bibliothèque elle-même n'existe qu'une seule et même fichier binaire. La bibliothèque est inclus dans le lien de la liste au moment de la compilation (c'est à dire: LDOPTS+=-lmylib pour un fichier de bibliothèque nommée mylib.a)
  3. DLL: Essentiellement le même comme un objet partagé, mais plutôt que d'être inclus dans le lien de la liste au moment de la compilation, la bibliothèque est chargé par dlopen()/dlsym() des commandes ainsi que la bibliothèque n'a pas besoin d'être présent au moment de la construction pour le programme à compiler. Aussi, la bibliothèque n'a pas besoin d'être présent (nécessairement) au démarrage de l'application, comme il est seulement nécessaire au moment de l' dlopen/dlsym des appels sont faits.
  4. Partagé Archive: Essentiellement la même qu'une bibliothèque statique, mais est compilé avec la fonction "exporter partagés" drapeau. La bibliothèque est inclus dans le lien de la liste au moment de la compilation (c'est à dire: LDOPTS+=-lmylibS pour un fichier de bibliothèque nommée mylibS.a). La distinction entre les deux est que cet indicateur supplémentaire est nécessaire si un objet partagé ou DLL veut lier statiquement partagé archive dans son propre code ET être en mesure de faire les fonctions de l'objet partagé disponible pour d'autres programmes, plutôt que de simplement en utilisant internes à la DLL. Ceci est utile dans le cas où quelqu'un vous offre une bibliothèque statique, et que vous souhaitez remballer comme une SORTE.

280voto

aleroot Points 30853

Une bibliothèque statique(.a) est une bibliothèque qui peut être lié directement dans l'exécutable final produit par l'éditeur de liens,c'est qu'elle contient, et il n'est pas nécessaire d'avoir de la bibliothèque dans le système où l'exécutable sera déployé.

Une bibliothèque partagée(.donc) est une bibliothèque qui est lié mais non inclus dans l'exécutable final, donc, sera chargé lorsque l'exécutable est lancé et doivent être présents dans le système où l'exécutable est déployé.

Une bibliothèque de liens dynamiques sur windows(.dll) est comme une bibliothèque partagée(.donc) sur linux, mais il existe quelques différences entre les deux implémentations qui sont liées à l'OS (Windows vs Linux) :

Une DLL peut définir deux types de fonctions: exportées et interne. Les fonctions exportées sont destinés à être appelé par d'autres modules, ainsi que de l'intérieur de la DLL, où ils sont définis. Fonctions internes sont généralement destinées à être appelées qu'à partir de la DLL, où ils sont définis.

Une SORTE de bibliothèque sur Linux n'a pas besoin spéciale à l'exportation déclaration pour indiquer exportable symboles, puisque tous les symboles sont disponibles à un interrogatoire de processus.

127voto

Matthew Walton Points 4497

J'ai toujours pensé que les Dll et les objets partagés sont juste des termes différents pour la même chose que Windows appelle Dll, tandis que sur les systèmes UNIX, ils sont des objets partagés, le terme général - bibliothèque liée dynamiquement - couvrant à la fois (même la fonction pour ouvrir un .donc sur UNIX s'appelle dlopen() après 'dynamic library').

Ils sont en effet uniquement lié au démarrage de l'application, cependant, votre notion de la vérification à l'encontre de l'en-tête de fichier est incorrect. Le fichier d'en-tête définit les prototypes qui sont nécessaires afin de compiler le code qui utilise la bibliothèque, mais au moment de la liaison à l'éditeur de liens regarde à l'intérieur de la bibliothèque elle-même, assurez-vous que l'fonctions, elle a besoin en réalité. L'éditeur de liens a trouver la fonction des organes, quelque part au moment de la liaison ou il va générer une erreur. Il le fait AUSSI qu'au moment de l'exécution, parce que, comme vous le faites justement remarquer la bibliothèque elle-même a peut-être changé depuis que le programme a été compilé. C'est pourquoi ABI stabilité est si important dans la plate-forme de bibliothèques, comme l'ABI change, c'est ce qui brise les programmes existants compilé avec les anciennes versions.

Les bibliothèques statiques sont juste des paquets de fichiers de l'objet tout droit sorti du compilateur, tout comme ceux que vous créez vous-même dans le cadre de votre projet de compilation, de sorte qu'ils se tiré dans et nourris à l'éditeur de liens exactement de la même manière, et les bits non utilisés sont déposés dans exactement de la même manière.

50voto

JoGusto Points 41

Je peux préciser tous les détails de Dll dans Windows pour aider à éclaircir ces mystères à mes amis ici sous *NIX-terre...

Une DLL est comme un fichier Objet Partagé. Les deux sont des images, prêt à charger en mémoire par le programme de chargeur de l'OS respectifs. Les images sont accompagnées par divers éléments de métadonnées à l'aide des linkers et les chargeurs de faire le nécessaire associations et utiliser la bibliothèque de code.

Les Dll de Windows ont une table d'exportation. Les exportations peuvent être par nom, ou par la position du tableau (numérique). La dernière méthode est considérée comme "vieille école" et est beaucoup plus fragile -- la reconstruction de la DLL et de changer la position de la fonction dans la table va dans le mur, alors qu'il n'y a pas de réel problème si reliant des points d'entrée par nom. Donc, oubliez ça comme un problème, mais juste être conscient qu'il est là si vous travaillez avec des "dinosaures" de code tels que la 3e partie fournisseur de libs.

Dll Windows est construit par la compilation et la liaison, comme vous le feriez pour un EXE (exécutable de l'application), mais les DLL est destinée à ne pas être seul, comme une SORTE est destiné à être utilisé par une application, soit par l'intermédiaire de chargement dynamique, ou par le lien de la liaison (la référence à ce qu'est incorporé dans l'exécutable de l'application de métadonnées, et les OS du programme chargeur automatique de charge référencés SO). Dll peuvent faire référence à d'autres Dll, tout comme SOs peut faire référence à d'autres SOs.

Dans Windows, Dll mettra à la disposition uniquement des points d'entrée. On les appelle les "exportations". Le développeur peut soit utiliser un compilateur de mots clés faire un symbole externe visible (pour les autres linkers et le chargeur dynamique), ou les exportations peuvent être inscrites dans un fichier de définition de module qui est utilisé au moment de la liaison quand la DLL elle-même est en cours de création. La pratique moderne est de décorer la définition de la fonction avec le mot-clé à exporter le nom du symbole. Il est également possible de créer des fichiers d'en-tête avec les mots-clés qui vont déclarer que symbole importée à partir d'une DLL en dehors de l'actuelle unité de compilation. Rechercher les mots-clés __declspec(dllexport) et __ _ _ declspec(dllimport) pour plus d'informations.

L'une des caractéristiques les plus intéressantes de Dll, c'est qu'ils peuvent déclarer une norme "lors du chargement/déchargement" fonction de gestionnaire. Chaque fois que la DLL est chargée ou déchargée, le fichier DLL peuvent effectuer certaines d'initialisation ou de nettoyage, selon le cas. Cela correspond bien en avoir un DLL comme un objet-orienté gestionnaire de ressources, comme un pilote de périphérique ou un objet partagé de l'interface.

Lorsqu'un développeur veut utiliser un déjà construit DLL, elle doit soit faire référence à un "bibliothèque d'exportation" (*.LIB) créé par la DLL développeur lorsqu'elle a créé la DLL, ou elle doit explicitement charger la DLL au moment de l'exécution et de la demande du point d'entrée d'adresse par nom par le biais du() LoadLibrary et GetProcAddress() mécanismes. La plupart du temps, de se lier à un fichier LIB (qui ne contient que l'éditeur de liens de métadonnées pour la DLL est exporté points d'entrée) est le chemin de la Dll de s'habituer. Le chargement dynamique est généralement réservés pour la mise en œuvre de "polymorphisme" ou "runtime configuration" dans le programme de comportements (l'accès à des add-ons ou plus tard fonctions, aka "plugins").

Le Windows façon de faire les choses peut causer une certaine confusion à la fois; le système utilise l' .LIB extension pour désigner à la fois la normale bibliothèques statiques (archives, comme POSIX *.un fichiers) et à l'exportation "stub" les bibliothèques nécessaires pour lier une application à une DLL au moment de la liaison. Donc, il faut toujours regarder pour voir si un *.LIB le fichier a le même nom *.Fichier DLL; sinon, les chances sont bonnes qu' *.Fichier LIB est une bibliothèque statique d'archives, et de ne pas exporter de liaison des métadonnées pour une DLL.

7voto

rapadura Points 1920

Vous avez raison statique fichiers sont copiés à l'application au lien-temps, et que les fichiers partagés sont juste vérifié au moment de la liaison et chargé lors de l'exécution.

Le dlopen appel n'est pas seulement pour les objets partagés, si le demandeur souhaite le faire au moment de l'exécution en son nom, sinon les objets partagés sont chargés automatiquement au démarrage de l'application. DLL et .sont donc la même chose. le dlopen existe, afin d'ajouter encore plus fine de chargement dynamique des capacités pour les processus. Vous n'avez pas à utiliser dlopen-vous d'utiliser les Dll, ce qui arrive trop au démarrage de l'application.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X