Question

Quelqu'un peut-il expliquer comment fonctionne la compilation?

Je ne peux pas sembler comprendre comment fonctionne la compilation ..

Pour être plus précis, voici un exemple .. Je suis en train d'écrire un code dans MSVC ++ 6 pour charger un état Lua ..

Je l'ai déjà:

  • définir les répertoires supplémentaires pour la bibliothèque et inclure des fichiers dans les répertoires droite
  • utilisé extern "C" (parce que Lua est C seulement ou si je l'entends)
  • include'd les fichiers d'en-tête droite

Mais je suis toujours obtenir des erreurs dans MSVC ++ 6 sur les symboles externes non résolus (pour les fonctions Lua que j'ai utilisé).

Autant que je voudrais savoir comment résoudre ce problème et passer à autre chose, je pense qu'il serait beaucoup mieux pour moi si je suis venu à comprendre les processus sous-jacents, de sorte que tout le monde pouvait peut-être écrire une bonne explication pour cette ? Ce que je suis à la recherche de savoir est le processus .. Il pourrait ressembler à ceci:

Etape 1:

  • Entrée: code source (s)
  • processus: Parsing (peut-être ajouter plus de détails ici)
  • Sortie: tout ce qui est sortie ici ..

Étape 2:

  • Entrée: Quelle qu'ait été la sortie de l'étape 1, plus peut-être tout ce qui est nécessaire (les bibliothèques DLL .donc .lib??)
  • processus: tout ce qui est fait avec l'entrée
  • Sortie: tout ce qui est sortie

et ainsi de suite ..

Merci ..

Peut-être cela explique quels symboles sont, le code ou quoi exactement ce « lien » est, ce « objet » est ..

Merci .. Désolé pour être un Noob ..

P.S. Cela ne doit pas être un langage spécifique .. Mais ne hésitez pas à l'exprimer dans la langue que vous êtes le plus à l'aise dans ..:)

EDIT : De toute façon, je suis en mesure d'obtenir les erreurs résolues, il se trouve que je dois ajouter manuellement le fichier .lib au projet; simplement spécifier le répertoire de la bibliothèque (où le .lib réside) dans les paramètres IDE ou les paramètres du projet ne fonctionne pas ..

Cependant, les réponses ci-dessous ont un peu m'a aidé à comprendre le processus mieux. Un grand merci .. Si quelqu'un veut encore écrire un guide complet, s'il vous plaît faire ..:)

EDIT : Juste pour référence supplémentaire, j'ai trouvé deux articles par un auteur (Mike Diehl) pour expliquer ce très bien .. :) examen du processus de compilation: Part 1 examen du processus de compilation: Part 2

Était-ce utile?

La solution

De la source à l'exécutable est généralement un processus en deux étapes pour C et langages associés, bien que l'EDI présente probablement cela comme un processus unique.

1 / vous codez votre source et l'exécuter par le compilateur. Le compilateur à ce stade a besoin de votre source et les fichiers d'en-tête de l'autre des choses que vous allez faire le lien avec (voir ci-dessous).

Compilation consiste à transformer vos fichiers source en fichiers objet. fichiers objets ont votre code compilé et suffisamment d'informations pour savoir ce que d'autres choses dont ils ont besoin, mais pas où trouver cette autre substance (par exemple, les bibliothèques LUA).

2 / Linking, la prochaine étape, combine tous vos fichiers d'objets avec des bibliothèques pour créer un fichier exécutable. Je ne vais pas couvrir un lien dynamique ici depuis compliquera l'explication avec peu d'avantages.

Non seulement vous devez spécifier les répertoires où l'éditeur de liens peut trouver l'autre code, vous devez spécifier la bibliothèque réelle contenant ce code. Le fait que vous obtenez indique que unresolved externals vous ne l'avez pas fait.

À titre d'exemple, considérons le code C simplifié suivant (xx.c) et commande.

#include <bob.h>
int x = bob_fn(7);

cc -c -o xx.obj xx.c

compile le fichier à xx.obj bob.h. Le prototype contient bob_fn() pour que la compilation afin -c réussira. Le -o xx.obj charge le compilateur pour générer un fichier objet plutôt que d'un fichier exécutable et le /bob/libs/libbob.so définit le nom du fichier de sortie.

Mais la réelle code pour n'est pas dans xx.exe le fichier d'en-tête, mais dans libbob.so, ainsi lien, vous avez besoin quelque chose comme:

cc -o xx.exe xx.obj -L/bob/libs;/usr/lib -lbob

crée à partir -L -l, en utilisant les bibliothèques (cherchées dans les chemins donnés) de la forme libbob.a (la lib et .donc sont généralement ajoutés par l'éditeur de liens). Dans cet exemple, définit le chemin libbob.dll de recherche pour les bibliothèques. Le spécifie une bibliothèque bob.a pour trouver à inclure dans le fichier exécutable si nécessaire. L'éditeur de liens prend généralement la « bob » et trouve le premier fichier de bibliothèque pertinente dans le chemin de recherche spécifié par bob.dll.

Un fichier de bibliothèque est vraiment une collection de fichiers d'objets (sorte de la façon dont un fichier zip contient plusieurs autres fichiers, mais pas nécessairement compressé) - lorsque la première occurrence pertinente d'un se trouve externe non définie, le fichier objet est copié à partir du bibliothèque et ajouté à l'exécutable comme votre fichier bob.so. Cela continue généralement jusqu'à ce qu'il n'y a pas plus non résolus externals. La bibliothèque « pertinente » est une modification du texte « bob », il peut chercher <=>, <=>, <=>, <=>, <=>, et ainsi de suite <=>. La pertinence est décidée par l'éditeur de liens lui-même et doit être documenté.

Comment ça marche dépend de l'éditeur de liens, mais cela est essentiellement cela.

1 / Tous vos fichiers objets contiennent une liste de non résolus externals dont ils ont besoin d'avoir résolu. L'éditeur de liens rassemble tous ces objets et fixe les liens entre eux (résout autant que possible externals).

2 / Ensuite, pour chaque externe toujours non résolues, l'éditeur de liens peignes les fichiers de bibliothèque à la recherche d'un fichier objet qui peut satisfaire le lien. Si elle le trouve, il le tire dans -. Cela peut entraîner d'autres non résolus que l'externals objet tiré ce dernier peut avoir sa propre liste de externals qui doivent être satisfaits

3 / Répétez l'étape 2 jusqu'à ce qu'il n'y a pas externals plus non résolues ou aucune possibilité de les résoudre dans la liste des bibliothèques (ce qui est l'endroit où votre développement était, puisque vous ne l'aviez pas inclus le fichier de bibliothèque LUA).

La complication je l'ai mentionné plus tôt est un lien dynamique. C'est là que vous liez avec un talon d'une routine (une sorte de marqueur) plutôt que la routine réelle, qui est ensuite réglée au moment de la charge (lorsque vous exécutez l'exécutable). Des choses telles que les contrôles communs Windows sont dans ces DLL afin qu'ils puissent changer sans avoir à relier les objets dans un nouvel exécutable.

Autres conseils

Étape 1 - compilateur:

  • Entrée: fichier code source [s]
  • Process: reconnaissance de code source et de traduire en code machine
  • Sortie: le fichier de l'objet [s], qui se composent [s] de:
    • Les noms des symboles qui sont définis dans cet objet, et que ce fichier objet « exportations »
    • Le code de la machine associée à chaque symbole qui est défini dans ce fichier objet
    • Les noms des symboles qui ne sont pas définis dans ce fichier objet, mais sur lequel le logiciel dans ce fichier objet dépend et auquel il doit ensuite être lié, à savoir des noms que ce fichier objet « importations »

Étape 2 - Liaison:

  • Entrée:
    • Fichier objet [s] de l'étape 1
    • Bibliothèques d'autres objets (par exemple de l'O / S et d'autres logiciels)
  • processus:
    • Pour chaque objet que vous souhaitez associer
    • Obtenir la liste des symboles d'objet ces importations
    • Trouver ces symboles dans d'autres bibliothèques
    • Lier les bibliothèques correspondant à vos fichiers objets
  • Sortie: un seul fichier exécutable, ce qui inclut le code de la machine de tous vos objets, ainsi que les objets de bibliothèques qui ont été importés (liés) à vos objets
  • .

Les deux étapes principales sont la compilation et la liaison.

Compilation prend des unités de compilation unique (ce sont simplement des fichiers source, avec tous les en-têtes qu'ils comprennent), et créer des fichiers d'objets. Maintenant, dans les fichiers d'objets, il y a beaucoup de fonctions (et d'autres choses, comme des données statiques) définies à des emplacements spécifiques (adresses). Dans l'étape suivante, la liaison, un peu d'informations supplémentaires au sujet de ces fonctions est également nécessaire: leur nom. Ainsi, ceux-ci sont également stockés. Un seul fichier objet peut faire référence à des fonctions (parce qu'il veut les appeler quand le code est exécuté) qui sont en fait dans d'autres fichiers d'objets, mais étant donné que nous avons affaire à un seul fichier d'objet ici, seules les références symboliques (leurs « noms ») à les autres fonctions sont stockées dans le fichier objet.

Ensuite vient relier (nous allons nous limiter à l'électricité statique reliant ici). Cette liaison est où les fichiers objets qui ont été créés dans la première étape (soit directement, soit après avoir été jetés ensemble dans un fichier .lib) sont pris ensemble et un exécutable est créé. Dans l'étape, toutes ces références symboliques à partir d'un fichier objet ou lib à un autre sont résolus (si elles peuvent être), en regardant les noms dans l'objet correct, trouver l'adresse de la fonction de liaison, et de mettre les adresses dans le droit lieu.

Maintenant, pour expliquer quelque chose au sujet de la 'extern "C"' chose dont vous avez besoin:

C ne pas surcharger la fonction. Une fonction est toujours reconnaissable à son nom. Par conséquent, lorsque vous compilez le code sous forme de code C, seul le nom de la fonction est stockée dans le fichier objet.

C ++, cependant, a quelque chose appelé «surcharge fonction / méthode. Cela signifie que le nom d'une fonction ne suffit plus pour l'identifier. Les compilateurs créent donc des « noms » C de fonctions pour qui incluent les prototypes de la fonction (puisque le nom ainsi que le prototype identifiera de manière unique une fonction). Ceci est connu comme « nom mutiler ».

La spécification « extern « C » » est nécessaire lorsque vous voulez utiliser une bibliothèque qui a été compilé sous forme de code « C » (par exemple, les binaires Lua pré-compilés) à partir d'un projet C ++.

Pour votre problème exact: si elle ne fonctionne toujours pas, ces conseils peuvent vous aider: * Ont les binaires Lua été compilé avec la même version de VC ++? * Vous pouvez simplement compiler Lua vous, que ce soit au sein de votre solution VC, ou comme un projet distinct code C ++? * Êtes-vous sûr que vous avez toutes les choses « extern « C » » correcte?

Vous devez aller dans cadre du projet et ajouter un répertoire dans lequel vous avez cette bibliothèque LUA * .lib fichiers quelque part sur l'onglet « linker ». Paramètre appelé « y compris les bibliothèques » ou quelque chose, désolé, je ne peux pas regarder vers le haut.

La raison pour laquelle vous obtenez « symboles externes non résolus » est parce que la compilation en C ++ fonctionne en deux étapes. Tout d'abord, le code sera compilé, chaque fichier .cpp dans son propre fichier .obj, puis commence « linker » et se joindre à tout ce que les fichiers .obj dans le fichier .exe. fichier .lib est juste un tas de fichiers OBJ fusionné ensemble pour faire la distribution des bibliothèques juste un petit peu plus simple. Donc, en ajoutant tous les « #include » et la déclaration extern vous avez dit au compilateur que quelque part, il serait possible de trouver le code avec ces signatures, mais linker ne peut pas trouver ce code parce qu'il ne sait pas où ces fichiers .lib avec le code réel est placé.

Assurez-vous que vous avez lu REDME de la bibliothèque, en général, ils ont une explication assez détaillée de ce que vous aviez à faire pour l'inclure dans votre code.

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