Frage

Kann mir jemand erklären, wie Kompilierung funktioniert?

Ich kann nicht scheinen, um herauszufinden, wie Kompilierung funktioniert ..

Um genauer zu sein, hier ist ein Beispiel .. Ich versuche, einige Codes in MSVC ++ 6 zu schreiben .. einen Lua Zustand zu laden

Ich habe schon:

  • setzen die zusätzlichen Verzeichnisse für die Bibliothek und Include-Dateien auf die richtigen Verzeichnisse
  • verwendet extern "C" (da Lua C nur ist oder wie ich höre)
  • INCLUDE die richtigen Header-Dateien

Aber ich bin immer noch einige Fehler in MSVC ++ 6 über ungelöste externe Symbole bekommen (für die Lua-Funktionen, die ich verwendet).

So viel wie Ich mag wissen würde, wie dieses Problem zu lösen, und ziehen weiter, ich denke, es für mich viel besser wäre, wenn ich kam, um die zugrunde liegenden Prozesse beteiligt ist, zu verstehen, so könnte jemand vielleicht eine nette Erklärung schreibt für diesen ? Was ich suche der Prozess zu wissen .. Es könnte wie folgt aussehen:

Schritt 1:

  • Input: Source-Code (s)
  • Prozess: Parsing (vielleicht ausführliche hier hinzufügen)
  • Ausgabe: was Ausgabe hier ist ..

Schritt 2:

  • Input: Was auch immer Ausgang von Schritt 1 war, und vielleicht was sonst noch benötigt wird (Bibliotheken DLLs .so Lib???)
  • Prozess: was auch immer mit der Eingabe
  • erfolgt
  • Ausgabe: was auch immer ausgegeben

und so weiter ..

Danke ..

Vielleicht wird dies erklären, was Symbole sind, was genau „Verknüpfung“ ist, was „Objekt“ Code oder was auch immer ..

Danke .. Sorry für derart ein noob ..

P. S. Dies muss nicht sprachspezifisch sein .. aber ich fühle mich frei, um es in der Sprache auszudrücken Sie am bequemsten in ..:)

Bearbeiten : Wie auch immer, ich war in der Lage die Fehler behoben werden, stellt sich heraus, dass ich manuell die LIB-Datei in das Projekt; einfach die Angabe des Bibliotheksverzeichnis (wo die LIB befindet) in den IDE-Einstellungen oder Projekteinstellungen nicht funktioniert ..

Allerdings unter die Antworten etwas haben mir geholfen, den Prozess besser zu verstehen. Vielen Dank .. Wenn jemand will immer noch eine gründliche Anleitung schreiben, bitte ..:)

Bearbeiten : Nur für zusätzliche Referenz, fand ich zwei Artikel von einem Autor (Mike Diehl) ganz gut zu erklären .. :) Untersuchen des Kompilierungsprozesses: Part 1 Untersuchung der Compilation-Prozess: Teil 2

War es hilfreich?

Lösung

Von der Quelle bis ausführbar ist in der Regel ein zweistufiges Verfahren zur C und zugehörigen Sprachen, obwohl die IDE wahrscheinlich stellen dies als einen einzigen Vorgang.

1 / Sie Ihren Quellcode und es durch den Compiler laufen. Der Compiler in diesem Stadium braucht Ihre Quelle und die Header-Dateien von den anderen Sachen, die Sie gehen mit (siehe unten) zu verbinden.

Compilation besteht die Quelldateien in Objektdateien zu verwandeln. Objektdateien haben kompilierte Code und genügend Informationen zu wissen, was andere Dinge, die sie brauchen, aber nicht , wo die anderen Sachen finden (zum Beispiel der LUA-Bibliotheken).

2 / Linking, die nächste Stufe ist die Kombination all Ihre Objektdateien mit Bibliotheken eine ausführbare Datei zu erstellen. Ich werde nicht dynamische Verknüpfung decke hier, da dies die Erklärung mit wenig Nutzen erschweren.

Nicht nur müssen Sie die Verzeichnisse angeben, in dem der Linker den anderen Code finden kann, müssen Sie die aktuelle Bibliothek angeben, dass Code enthält. Die Tatsache, dass Sie nicht aufgelöste externe sind immer bedeutet, dass Sie dies nicht getan haben.

Als Beispiel betrachte man die folgende vereinfachte C-Code (xx.c) und Befehl.

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

cc -c -o xx.obj xx.c

Dies kompiliert die xx.c Datei xx.obj. Der bob.h enthält den Prototyp für bob_fn() so dass Kompilierung erfolgreich sein wird. Der -c weist den Compiler eine Objektdatei, anstatt eine ausführbare Datei und die -o xx.obj setzt die Ausgabedateinamen zu erzeugen.

Aber der tatsächliche Code für bob_fn() ist nicht in der Header-Datei, sondern in /bob/libs/libbob.so, so Link, müssen Sie so etwas wie:

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

Das schafft xx.exe von xx.obj, mit Bibliotheken (nach in den angegebenen Pfaden) der Form libbob.so (lib und .so werden vom Linker in der Regel hinzugefügt). In diesem Beispiel -L legt den Suchpfad für Bibliotheken. Die -l gibt eine Bibliothek für die Aufnahme in der ausführbaren Datei bei Bedarf zu finden. Der Linker in der Regel nimmt die „bob“ und findet die erste relevante Bibliotheksdatei in der Pfadsuche durch -L angegeben.

Eine Bibliotheksdatei ist wirklich eine Sammlung von Objektdateien (eine Art, wie eine ZIP-Datei mehrere andere Dateien enthält, aber nicht unbedingt komprimiert) - wenn das erste relevante Auftreten eines undefinierten externen gefunden wird, wird die Objektdatei aus der kopiert Bibliothek und die ausführbare Datei hinzugefügt genau wie Ihre xx.obj Datei. Dies setzt sich im Allgemeinen, bis es keine mehr nicht aufgelöste externe sind. Die 'relevant' Bibliothek ist eine Modifikation des "bob" text, es für libbob.a aussehen, libbob.dll, libbob.so, bob.a, bob.dll, bob.so und so weiter. Die Relevanz wird durch den Linker selbst entschieden und soll dokumentiert werden.

Wie es funktioniert, hängt von dem Linker, aber das ist im Grunde ist es.

1 / Alle Ihre Objektdateien enthalten eine Liste von ungelösten Äußerlichkeiten, die sie benötigen, gelöst haben. Der Linker fasst all diese Objekte und fixiert auf die Verbindungen zwischen ihnen (löst so viele Äußerlichkeiten wie möglich).

2 / Dann wird für jeden externen noch ungelöst, der Linker die Bibliotheksdateien der Suche nach einer Objektdatei Kamm, die die Verbindung befriedigen. Wenn er sie findet, es zieht ihn in -. Dies weiter nicht aufgelöste externe führen kann, wenn das Objekt gezogen in kann seine eigene Liste von Externen haben, die erfüllt sein müssen,

3 / Wiederholen Sie Schritt 2, bis es nicht mehr nicht aufgelöste externe oder keine Möglichkeit, sie aus der Bibliothek Liste der Lösung (das ist, wo Ihre Entwicklung bei war, da Sie nicht die LUA-Bibliothek-Datei enthalten waren).

Die Komplikationsrate ich bereits erwähnt ist eine dynamische Verbindung. Das ist, wo Sie mit einem Stummel einer Routine (eine Art Marker) verknüpfen und nicht die tatsächliche Routine, die später bei l gelöst istOAD Zeit (wenn Sie führen Sie die ausführbare). Dinge wie die allgemeinen Windows-Steuerelemente sind in diesem DLLs, so dass sie wechseln können, ohne die Objekte in eine neue ausführbaren Datei neu verknüpfen.

Andere Tipps

Schritt 1 - Compiler:

  • Input: Quellcode-Datei [s]
  • Prozess: Parsing-Quellcode und Übersetzung in Maschinencode
  • Ausgabe: Objektdatei [s], die aus [s] von:
    • Die Namen von Symbolen, die in diesem Objekt definiert sind und die diese Objektdatei „exportiert“
    • Die Maschinencode mit jedem Symbol zugeordnet, das in diesem Objektdatei
    • definiert ist
    • Die Namen von Symbolen, die nicht in dieser Objektdatei definiert sind, aber auf das die Software in dieser Objektdatei hängt und mit dem er anschließend verknüpft werden muß, das heißt Namen, die diese Objektdatei „Importe“

Schritt 2 - Verknüpfung:

  • Input:
    • Objektdatei [s] aus Schritt 1
    • Bibliotheken anderer Objekte (zum Beispiel aus dem O / S und andere Software)
  • Prozess:
    • Für jedes Objekt, das Sie verknüpfen möchten
    • Holen Sie die Liste der Symbole, die dieses Objekt Importe
    • Finden Sie diese Symbole in anderen Bibliotheken
    • Verknüpfen Sie die entsprechenden Bibliotheken auf Ihre Objektdateien
  • Ausgabe: eine einzelne, ausführbare Datei, die den Maschinencode von allen alle Objekte, sowie die Objekte aus Bibliotheken enthält, die (verknüpft), um Ihre Objekte importiert wurden
  • .

Die beiden Hauptschritte sind Kompilieren und Linken.

Compilation nimmt einzelne Übersetzungseinheiten (das sind einfach Quelldateien mit allen Header sie enthalten) und Objektdateien erstellen. Nun, in diesen Objektdateien, gibt es eine Menge von Funktionen (und anderen Sachen, wie statische Daten) definierten an bestimmten Stellen (Adressen). Im nächsten Schritt, die Verknüpfung, ein bisschen mehr Informationen über diese Funktionen ist ebenfalls erforderlich: ihre Namen. So werden diese ebenfalls gespeichert. Eine einzelne Objektdatei kann Funktionen (weil sie will, sie nennen, wenn sie Code ausgeführt wird), die tatsächlich in anderen Objektdateien sind, aber da wir es zu tun hat, um mit einer einzigen Objektdatei hier nur symbolische Referenzen (ihre ‚Namen‘) die anderen Funktionen in der Objektdatei gespeichert.

Als nächstes kommt die Verknüpfung (wir beschränken uns hier auf statische Linken). Linking ist, wo die Objektdateien, die im ersten Schritt erstellt wurden (entweder direkt oder nachdem sie zusammen in eine LIB-Datei geworfen wurden) zusammengenommen werden, und eine ausführbare Datei erstellt wird. In der Verknüpfungsschritt, all diese symbolische Referenzen von einem Objekt-Datei oder lib zum anderen werden aufgelöst (wenn sie sein können), indem Sie die Namen in das richtige Objekt aufzublicken, Suche nach der Adresse der Funktion, und setzen Sie die Adressen in der richtigen Platz.

Nun, zu erklären, etwas über die 'extern "C"', was Sie brauchen:

C nicht Funktion Überlastung hat. Eine Funktion ist immer erkennbar durch seinen Namen. Wenn Sie also Code als C-Code zu kompilieren, wird nur der Name der Funktion in der Objektdatei gespeichert wird.

C ++, hat jedoch etwas 'Funktion / Methode Überlastung' genannt. Dies bedeutet, dass der Name einer Funktion nicht mehr genug ist, um es zu identifizieren. C ++ Compiler erzeugen daher ‚Namen‘ für Funktionen, die die Prototypen der Funktion (da der Name und der Prototyp wird eindeutig eine Funktion identifizieren) umfassen. Dies ist bekannt als 'Name Mangeln'.

Die ‚extern‚C‘‘ Spezifikation ist erforderlich, wenn Sie eine Bibliothek verwenden möchten, die als ‚C‘ Code kompiliert wurde (zum Beispiel die vorkompilierte Lua Binärdateien) aus einem C ++ Projekt.

Für Ihr genaues Problem: Wenn es immer noch nicht funktioniert, könnten diese Hinweise helfen: * Werden die Lua-Binärdateien mit der gleichen Version von VC ++ kompiliert? * Können Sie einfach kompilieren Lua selbst, entweder in Ihrer VC-Lösung oder als separates Projekt als C ++ Code? * Sind Sie sicher, dass Sie alle ‚extern‚C‘‘ haben die Dinge richtig?

Sie haben in Projekteinstellung gehen und ein Verzeichnis hinzuzufügen, wo Sie die LUA-Bibliothek * LIB-Dateien irgendwo auf dem „Linker“ Registerkarte. Einstellung „einschließlich Bibliotheken“ oder etwas genannt, sorry ich kann es nicht sehen.

Der Grund, warum Sie „nicht aufgelöste externe Symbole“ erhalten, weil Kompilierung in C ++ in zwei Stufen arbeitet. Zuerst wird der Code kompiliert, jede CPP-Datei in einem eigenen OBJ-Datei, dann „Linker“ beginnt und kommen alle, die Dateien in EXE-Datei .obj. LIB-Datei ist nur ein Haufen von OBJ-Dateien zusammen Verteilung von Bibliotheken machen fusionierte nur ein wenig simplier. So durch die ganze „#include“ Hinzufügen und extern Erklärung gesagt, den Compiler, dass irgendwo wäre es möglich, Code zu finden, mit diesen Signaturen aber Linker kann nicht diesen Code finden, weil sie nicht wissen, wo diese LIB-Dateien mit den tatsächlichen Code gesetzt wird.

Stellen Sie sicher, REDME der Bibliothek gelesen haben, in der Regel haben sie ziemlich detaillierte Erklärung dessen, was Sie es in Ihrem Code zu tun hatte, aufzunehmen.

Sie möchten vielleicht auch dies überprüfen: Compiler, Assembler, Linker und LOADER: EINE KURZE GESCHICHTE .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top