Pourquoi les bibliothèques liables statiques et dynamiques sont-elles différentes?

Si les deux contiennent du code compilé, pourquoi ne pouvons-nous pas charger les fichiers" statiques " à l'exécution et pourquoi ne pouvons-nous pas créer de lien avec les bibliothèques dynamiques au moment de la compilation? Pourquoi existe - t-il un besoin de formats séparés pour contenir du code "autonome"? Ce qui doit être conservé dans un seul qui justifie la différence?

28
demandé sur Brian Lyttle 2011-05-31 01:59:40

6 réponses

Les bibliothèques statiques sont de vraies bibliothèques en ce sens qu'elles contiennent une bibliothèque de fichiers objets. Chaque fichier objet est souvent créé à partir d'un fichier source unique et contient du code machine ainsi que des informations sur les données requises pour le code. Au cours de l'étape de lien, l'éditeur de liens sélectionnera les fichiers objets nécessaires et les combinera en un exécutable.

Une partie importante du code machine est que les sauts, les appels et les pointeurs de données devront contenir des adresses de mémoire réelles. Cependant, si une fichier objet doit appeler une autre fonction dans un autre fichier objet, il ne peut se référer à cette fonction en utilisant un symbole. Lorsque l'éditeur de liens combine les fichiers objet en code exécutable, les références de symboles sont résolues et transformées en adresses mémoire réelles.

Une bibliothèque dynamique est un code exécutable qui peut être chargé dans la mémoire et exécuté immédiatement. Sur certains systèmes d'exploitation il peut y avoir une étape supplémentaire où le code est rebasé en déplaçant le code exécutable vers un autre emplacement et cela nécessite que toutes les adresses absolues dans le code soient décalées d'un montant fixe. Cette opération est encore beaucoup plus rapide que la combinaison de fichiers objets et la résolution de symboles effectués par l'éditeur de liens.

Pour résumer:

  • les bibliothèques statiques contiennent des éléments de code exécutable qui utilisent des symboles pour faire référence à d'autres éléments de code exécutable
  • les bibliothèques dynamiques (et exécutables) contiennent du code exécutable maintenant placé à des emplacements fixes permettant de remplacer les symboles par des adresses mémoire

Si vous avez déjà essayé de lier un projet de taille raisonnable, vous aurez remarqué que cela prend un temps non trivial, probablement plus long que vous ne voudriez attendre pour démarrer une application. Cela explique en quelque sorte pourquoi vous ne pouvez pas exécuter de bibliothèques statiques. Et les bibliothèques dynamiques ont été optimisées et dépouillées pour ne contenir rien sauf du code exécutable qui les rend impropres à l'utilisation en tant que bibliothèques statiques.

21
répondu Martin Liversage 2011-05-30 23:00:22

Le code d'un fichier objet n'est pas lié. Il contient des références implicites à des fonctions externes qui n'ont pas encore été résolus.

Lorsque des fichiers objet sont liés pour créer une DLL, l'éditeur de liens parcourt toutes ces références externes et trouve d'autres bibliothèques (statiques ou dynamiques) qui peuvent les satisfaire. Une référence à un nom dans une bibliothèque statique est résolue en incluant le corps de cette fonction (ou autre) dans la DLL. S'il fait référence à une bibliothèque dynamique, le nom de la DLL et la fonction référencée sont incluses dans la DLL.

En fin de compte, il n'y a aucune raison que ait pour être le cas. En théorie, vous pouvez écrire le chargeur pour faire tout cela chaque fois que vous chargez un fichier. C'est fondamentalement juste une optimisation: l'éditeur de liens fait les parties relativement lentes du travail. Les références aux DLL sont laissées, mais elles sont résolues au point qu'il est assez rapide pour le chargeur de trouver et de charger le fichier cible (si nécessaire) et de résoudre les fonctions référencées. Lorsque l'éditeur de liens fait son travail, il fait beaucoup plus en parcourant de longues listes de définitions pour trouver celles qui vous intéressent, ce qui est un peu plus lent.

6
répondu Jerry Coffin 2011-05-30 22:35:27

Note: la réponse suivante est Pas agnostique de la plate-forme, mais spécifique aux systèmes basés sur ELF et à d'autres systèmes similaires. Quelqu'un d'autre peut remplir les détails pour d'autres systèmes.

Qu'est Ce qu'une bibliothèque statique?

Une bibliothèque statique est une collection de *.o fichiers dans une archive. Chaque fichier peut contenir des références à des symboles indéfinis qui doivent être résolus par l'éditeur de liens, par exemple, votre bibliothèque peut avoir une référence à printf. La bibliothèque ne fournit pas toute indication sur l'endroit où printf sera trouvé, il est prévu que l'éditeur de liens le trouvera dans l'une des autres bibliothèques dans lesquelles il est demandé de lier.

Supposons que votre bibliothèque contienne le code suivant:

read_png.o
write_png.o
read_jpg.o
write_jpg.o
resize_image.o
handle_error.o

Si une application utilise uniquement read_png et write_png, les autres morceaux de code ne sera pas chargé dans l'exécutable (à l'exception handle_error, qui est appelé à partir de read_png et write_png).

Nous ne pouvons pas charger une bibliothèque statique à l'exécution car:

  • L'éditeur de liens ne sait pas où trouver des objets externes, par exemple, printf.

  • Ce serait lent. Les bibliothèques dynamiques sont optimisées pour un chargement rapide.

  • Les bibliothèques Statiques n'ont pas la notion d'espaces de noms. Je ne peux pas définir mon propre handle_error car cela entrerait en conflit avec la définition de la bibliothèque.

Qu'est Ce qu'une bibliothèque dynamique?

Une bibliothèque dynamique, sur les systèmes ELF, est le même type d'objet qu'un exécutable. Il exporte également plus de symboles, un exécutable n'a besoin que d'exporter _start. Les bibliothèques dynamiques sont optimisées afin que le tout puisse être mappé directement dans la mémoire.

Si vous avez un appel à printf dans votre bibliothèque dynamique, il y a des exigences supplémentaires au-delà des exigences pour les bibliothèques statiques:

  • Vous devez spécifier la bibliothèque a printf.

  • Vous devez appeler la fonction dans une manière spéciale qui permet à l'éditeur de liens insérer l'adresse de printf. Dans une bibliothèque statique, l'éditeur de liens peut simplement modifier votre code et insérez l'adresse directement, mais ce n'est pas possible avec les bibliothèques partagées.

Nous ne voulons pas utiliser de bibliothèques dynamiques pour lier statiquement car:

  • Nous ne pouvons pas lier seulement une partie d'une bibliothèque dynamique. Même si notre exécutable n'appelle jamais read_jpg, Il est inclus car les bibliothèques dynamiques sont tout ou rien.

  • La surcharge supplémentaire pour les appels de fonction est inutile, même si elle est Petite.

Résumé

La Compilation ressemble à ceci:

Source  ==compile==>  Object  ==link==>  Executable / Shared Library

Une bibliothèque statique est une archive pleine d'objets qui n'ont pas encore été liés. Il y a beaucoup de travail reste à faire.

Une bibliothèque partagée est un produit final lié, prêt à être chargé en mémoire.

Les bibliothèques statiques ont été inventées en premier. Si les deux ont été inventés en même temps, il est possible qu'ils seraient beaucoup plus similaires.

4
répondu Dietrich Epp 2011-05-30 22:56:14

Il N'y a aucune raison fondamentale pour laquelle vous ne pouvez pas utiliser les fichiers de bibliothèque statique (.a) en tant que bibliothèques dynamiques, en les chargeant et en les reliant au début du programme ou même dynamiquement au moment de l'exécution. Cependant, ils n'ont pas été spécialement compilés et préparés pour exécuter un mappage de mémoire à une adresse arbitraire (même l'alignement n'est pas nécessairement correct!), de sorte que le code du chargeur devrait allouer de la mémoire, lire les objets nécessaires à partir des fichiers .a dans cette mémoire, et effectuer des modifications majeures dessus. Et bien sûr, aucun de ces souvenirs ne serait partageable. Ainsi, c'est probablement une très mauvaise idée...

3
répondu R.. 2011-05-31 13:54:10

Statique lib = = tarball alors que dynamique = =image contiguë partiellement liée

Une bibliothèque statique est juste une archive1 de .o or.fichiers obj'. Quand un exécutable est lié aux modules référencés (et ceux qu'ils référencent, puis ceux qu'ils référencent, puis ... etc) sont copiés hors de la lib statique et cloués à la fin du programme principal. Tout cela est paginé en mémoire comme un seul "objet"du système d'exploitation.

Une bibliothèque dynamique il suffit de prendre tous les éléments de la bibliothèque statique, de les lier ensemble (résoudre les relations intra-muros), puis de mapper le tout en mémoire. (La pagination de demande peut rendre une présence partielle de mémoire réalisable.) Une certaine quantité de Tripotage est nécessaire lors du lancement de programmes dynamiques afin de connecter le programme principal (qui sera "statiquement" lié dans ses propres modules) à la bibliothèque partagée à l'échelle du système. Parfois, ce Tripotage est retardé par élément de liaison jusqu'à ce qu'un élément donné l'appel est fait. Dans un balayage très large et trop conceptuel, on pourrait catégoriser la liaison statique comme Chargement impatient et dynamique comme chargement paresseux.

Il y a des avantages et des inconvénients avec les bibliothèques statiques.

Non DLL enfer (aka dépendance enfer)
empreinte mémoire beaucoup plus petite pour les petits mélanges de processus d'exécution
- empreinte mémoire beaucoup plus grande pour de grands mélanges de processus d'exécution les programmes
- ne Pouvez pas partager une bibliothèque de code de la mémoire entre les processus sauf lorsqu'ils exécutent le même programme
- Un grand nombre de programmes (comme Linux/Windows/Mac empreintes) prennent beaucoup d'espace printf al sont dupliqués dans chaque image
- Il est difficile, sinon impossible, de corriger les bogues de sécurité, originaires des bibliothèques
- Il est difficile, voire impossible, de mettre à jour une seule bibliothèque
Il est difficile sinon impossible de mettre à jour une bibliothèque seule et de casser votre programme


1. En fait, ils ne sont pas au format tar(1), mais c'est lié.

1
répondu DigitalRoss 2011-06-01 00:01:39

La différence est:

  • bibliothèques statiques et compilées et liées
  • les bibliothèques dynamiques sont liées

Références à

0
répondu Paul Sweatte 2015-01-09 03:38:32