C-Header-Dateien und Kompilierung / Verknüpfung
Weiß ich, dass header-Dateien haben die forward-Deklaration der verschiedenen Funktionen, structs, etc. in den .c
- Datei, die 'Anrufe' die #include
, richtig? Soweit ich das verstanden habe, die "Gewaltenteilung", tritt wie diese:
Header-Datei: func.h
- enthält vorwärts-Deklaration von Funktion
int func(int i);
C-Quellcode-Datei: func.c
- enthält die eigentliche definition einer Funktion
#include "func.h" int func(int i) { return ++i ; }
C-source-Datei source.c
(die "eigentliche" Programm):
#include <stdio.h>
#include "func.h"
int main(void) {
int res = func(3);
printf("%i", res);
}
Meine Frage ist: zu sehen, dass die #include
ist einfach eine compiler-Direktive, kopiert den Inhalt des .h
in der Datei, die #include
ist in, wie funktioniert das .c
Datei wissen, wie Sie tatsächlich führen Sie die Funktion aus? Allen, die es bekommen ist die int func(int i);
, so wie es eigentlich die Funktion? Wie sieht es den Zugriff auf die eigentliche definition von func
? Hat die header beinhalten eine Art 'Zeiger', der sagt "das ist meine definition, da drüben!"?
Wie funktioniert es?
Linker
die Lösung der Definitionen und sicherzustellen, dass die Dinge, die Sie behauptet zu existieren, während der Kompilierung tatsächlich vorhanden sind. InformationsquelleAutor der Frage Aristides | 2013-08-31
Du musst angemeldet sein, um einen Kommentar abzugeben.
Uchia Itachi gab die Antwort. Es ist die linker.
Verwendung von GNU C compiler
gcc
würden Sie kompilieren eine one-file-Programm wieAber kompilieren die zwei (oder mehrere) Datei, Programm wie beschrieben, in deinem Beispiel, würden Sie haben, um Folgendes zu tun:
Jede Objekt-Datei hat externe Symbole (Sie können denken, es als öffentliche Mitglieder). Funktionen sind standardmäßig während externe (Globale) Variablen werden standardmäßig intern. Man könnte dieses Verhalten ändern, indem die Definition
oder
Bei der Begegnung mit einem Aufruf einer Funktion nicht definiert in der main-Modul, der linker sucht alle Objekt-Dateien und Bibliotheken) als Eingabe für das Modul, in dem die aufgerufene Funktion definiert ist. Standardmäßig werden Sie wahrscheinlich haben einige Bibliotheken im Zusammenhang mit Ihrem Programm, das ist, wie Sie verwenden können
printf
, es ist bereits kompiliert in einer Bibliothek.Wenn Sie wirklich interessiert sind, versuchen manche Assembler-Programmierung. Diese Namen entsprechen den Bezeichnungen in Assembler-code.
InformationsquelleAutor der Antwort Emil Vatai
Es ist der linker, der verarbeitet alles. Der compiler gibt einfach eine spezielle Reihenfolge in die Objektdatei zu sagen: "ich habe dieses externe symbol
func
bitte auflösen" für den linker. Dann linker sieht, und sucht alle anderen Objekt-Dateien und Bibliotheken, die für das symbol.InformationsquelleAutor der Antwort Some programmer dude
Einer Erklärung des symbols, ohne eine definition innerhalb der selben compilation unit teilt dem compiler zu kompilieren mit einem Platzhalter für das symbol s-Adresse in eine Objekt-Datei.
Den linker werden sehen, dass eine definition für das symbol erforderlich ist, und wird sich für externe Definitionen des symbols in Bibliotheken und anderen Objekt-Dateien.
Wenn der linker findet eine definition, die Platzhalter in der ursprünglichen Objekt-Datei ersetzt werden, mit der gefundenen Adresse in die endgültige ausführbare Datei.
InformationsquelleAutor der Antwort Henrik
Den header Zugriff nicht nur auf andere
.c
Dateien in das gleiche Programm, aber ebenso auf Bibliotheken, verteilt in binäre form. Die Beziehung eines.c
- Datei zu einer anderen ist genau das gleiche wie eine Bibliothek, die von einem anderen abhängt.Da eine Programmier-Schnittstelle muss in form von text, egal, das format, die Implementierung, den header-Dateien Sinn machen als eine Trennung.
Wie andere erwähnt haben, das Programm, das behebt Funktion Aufrufe und Zugriffe zwischen Bibliotheken und Quellen (übersetzungseinheiten) wird als linker.
Den linker nicht mit Kopfzeilen arbeiten. Es macht einfach eine große Tabelle mit allen Namen, die definiert sind in allen übersetzungseinheiten und Bibliotheken, dann ist links die Namen der code-Zeilen, die Zugang zu Ihnen haben. Archaische Verwendung von C erlaubt auch den Aufruf einer Funktion ohne Implementierung Erklärung; es war nur davon ausgegangen, dass jede Undefinierte Typ war ein
int
.InformationsquelleAutor der Antwort Potatoswatter
In der Regel, wenn Sie kompilieren eine Datei wie diese:
Du wirklich anrufen, eine Treiber-Programm, das das folgende tut:
cpp
.cc1
as
(gas, der GNU Assembler).collect2
, die auch verwendetld
(der GNU linker).In der Regel während der ersten 3 Phasen, erstellen Sie ein einfaches Objekt-Datei (
.o
- Erweiterung), die erzeugt wird, durch Zusammenstellung einer compilation-unit (das ist eine .c-Datei mit der #include-und andere Richtlinien ersetzt durch den Präprozessor).Die 4. Etappe ist die einzige, der das fertige executable erstellt. Nach der Kompilierung von einer Einheit, die compiler-mehrer-Zeichen-code-Stücken, die als Referenzen aufgelöst werden müssen durch den linker. Der linker hat die Aufgabe, die Suche unter den vielen compilation-Einheiten und lösen die Verweise auf externe Zusammenstellung Einheiten.
InformationsquelleAutor der Antwort NlightNFotis