2009-02-06 3 views
12

Je tente de construire une bibliothèque statique C/C++ en utilisant Visual Studio 2005. Comme la sélection de la bibliothèque d'exécution est une option de compilation, je suis obligé de construire quatre variantes de ma bibliothèque, une pour chaque variation de la bibliothèque d'exécution :Pourquoi la bibliothèque d'exécution est-elle une option du compilateur plutôt qu'une option de l'éditeur de liens?

  • /MT - bibliothèque d'exécution statique
  • /MD - bibliothèque d'exécution DLL
  • /MTd - débogage bibliothèque d'exécution statique
  • /MDd - débogage bibliothèque d'exécution DLL

Ce sont compilateur options, pas les options de l'éditeur de liens. Venant d'un arrière-plan Linux, cela semble étrange. Les différentes bibliothèques d'exécution ont-elles différentes conventions d'appel ou quelque chose? Pourquoi les différentes bibliothèques d'exécution ne peuvent-elles pas être résolues au moment de la liaison, c'est-à-dire lorsque je lierai l'application qui utilise ma bibliothèque statique?

+0

Bien qu'il semble y avoir de bonnes raisons à cela dans les réponses - je suis d'accord avec vous. Je finis toujours par chercher ce réglage au mauvais endroit. Même chose avec les paramètres En-têtes précompilés - il a sa propre catégorie au lieu d'être quelque chose dans la section Préprocesseur. –

Répondre

7

Un effet secondaire des définitions C de préprocesseur comme _DLL et _DEBUG que zdan mentionné:

Certaines structures de données (tels que les conteneurs STL et itérateurs) peut être dimensionné différemment dans le temps d'exécution de débogage, probablement en raison des caractéristiques telles que _HAS_ITERATOR_DEBUGGING et _SECURE_SCL. Vous devez compiler votre code avec structure definitions that are binary-compatible with the library you're linking to.

Si vous mélangez et les fichiers d'objets de correspondance qui ont été compilés contre différentes bibliothèques d'exécution, vous obtiendrez des avertissements de l'éditeur de liens tels que les suivants:

warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs 
0

Je crois que la raison derrière cela est que le code SEH (gestionnaire d'exception structuré) sera généré différemment selon la bibliothèque d'exécution avec laquelle vous liez.

1

Si vous ignorez l'exécution statique, vous obtenez les mêmes options que Linux. Je sais que l'exécution statique peut être utile mais je n'en ai jamais vraiment eu besoin. En outre, cela conduit à des problèmes potentiels concernant l'allocation/désallocation de la mémoire et, par conséquent, je trouve qu'il est plus facile de simplement utiliser le DLL runtime. Avoir la version Release/Debug est la même chose que Linux/Unix.
Cependant, pour des raisons d'efficacité, je construis aussi des versions à un seul thread et à plusieurs threads de bibliothèques.

8

Ces options peuvent ajouter des définitions (__DLL et __DEBUG par exemple) qui sont utilisées dans les fichiers d'en-tête de la bibliothèque d'exécution. Une chose courante à faire est d'ajouter __declspec (dllimport) aux déclarations de fonction quand elles sont liées dynamiquement.

Le compilateur semble également les utiliser pour aider l'éditeur de liens à se lier aux bibliothèques correctes. Ceci est expliqué dans le MSDN.

3

Le compilateur doit savoir si vous générez du code monothread ou multithread. Par défaut, le compilateur génère du code thread-safe (multithread). Si vous changez la valeur par défaut, le compilateur change la bibliothèque d'exécution par défaut (vous pouvez toujours la remplacer dans les options de la commande de l'éditeur de liens, mais assurez-vous que la bibliothèque que vous choisissez a le même code structure en tant que vos fichiers d'objet: statique unique, statique multithread ou DLL multithread). Notez qu'il n'y a pas d'option DLL à un seul thread (par définition, la DLL de la bibliothèque d'exécution a été créée en tant que thread sécurisé, car elle est partagée par plusieurs applications).

+1

Il n'y a plus non plus d'exécution statique mono-thread (je ne suis pas sûr si cela a commencé dans VC2005 ou VC2008). –

0

Il est différent du code machine généré pour les DLL et les bibliothèques statiques.

Et sur Linux, vous devez faire de même, l'indicateur de compilation est appelé -fPIC si vous voulez construire une bibliothèque partagée. Sinon, sur AMD64 et SPARC (et peut-être d'autres), il va planter. Sur l'architecture i386, l'éditeur de liens est assez intelligent et ne partage pas la bibliothèque en mémoire, donc il ne va pas tomber en panne.

Questions connexes