Einbinden von externen Funktionen
-
Hallo,
ich bin relativ neu in der C/C++ Programmierung und möchte nun wissen wie man Funktionen, die in externen Dateien liegen, einbindet. Ich bin zurzeit am Lernen und soweit ich das verstanden habe bindet man eine Header-Datei, in der der Funktionsprototyp steht, (z.B. durch "#include max.h") ein . (Ich hoffe mal das das soweit richtig ist, falls nicht bitte verbessern) Nun steht die eigentliche Funktion ja in einer anderen Datei (z.B. max.c) und ich würde gern wissen woher der Compiler weiß in welcher Datei die eigentliche Funktion steht, da ja die einzige Anweisung die der Compiler kriegt die Einbindung von der Headerdatei ist. Ich könnte mir vorstellen das der Compiler nach einer Datei mit dem gleichen Namen und der Endung ".c" bzw. ".cpp" sucht aber in dem Buch, aus dem ich lerne, steht das leider nicht. Falls die Frage Compilerspezifisch ist, bitte ich einen Moderator den Thread zu verschieben.Steve0
-
Hallo
Das verabreiten der Includes erledigt der Compiler durch einfaches Textersetzen, das heißt der Include-Verweis wird komplett durch den gesamten Inhalt der angegebenen Datei ersetzt.
In der Headerdatei stehen dann all die bereitgestellten Symbole, die der Compiler verwnden kann. Diesem reichen auch reine Definitionen, er brnaucht keine Implementationen. Findet der Compiler auch nach dem Include-Ersatz ein Symbol nicht, kommt ein entsprechender Compilerfehler- "Symbol unknown".Als nächstes wird der Linker aufgerufen um aus den durch den Compiler enstandenen Objekt-Dateien zu einem vollständigen Programm zusammenzusetzen. Dabei muß der Linker zugriff auf alle diese Dateien haben, also alle Pfade kennen. Findet der Linker ein Symbol nicht, kommt ein entsprechender Linkerfehler : "Unresolved External"
bis bald
akari
-
Danke schonmal.
Aber irgentwie verstehe ich nicht ganz was du meinst. Als Erstes weiß ich leider nicht was du mit Symbolen meinst. Dann meintest du "Dabei muß der Linker...alle Pfade kennen" aber woher kennt er den Pfad von der Funktionsdatei, in der steht was die Funktion machen soll (also der Code)? Man übergibt ja bloss den Pfad der Headerdatei.Steve0
-
Hallo
Als Erstes weiß ich leider nicht was du mit Symbolen meinst.
Symbole ist der Überbegriff für alles was in C++ definieren werden kann, also Funktionen, Klassen, Variablen etc.
aber woher kennt er den Pfad von der Funktionsdatei, in der steht was die Funktion machen soll (also der Code)?
Stell es dir am einfachsten so vor : Der Compiler bzw. der Linker macht aus deinem Quellcode einen großen Pool, in dem alles eindeutig definiert sein muß. Es darf also keine zwei oder mehrere Symbole geben, die in einem Scope (Gültigkeitsbereich) denselben Namen haben.
Damit kann der Linker immer genau nachvollziehen, welches Symbol aus welcher Objektdatei zu verwenden ist. Da der Linker aber nur reine Dateinamen ohne Pfadangaben bekommt, braucht er noch alle zu verwendenen Verzeichnisse, wo die Datei liegen können.bis bald
akari
-
Entweder bin ich zu blöd das zu begreifen oder ich hab die Frage nicht richtig formuliert.
Also, in meinem Buch wird erklärt das Funktionen die in externen Dateien liegen auch eine Header-Datei benötigen (jedenfalls so ähnlich). D.h. ich habe jetzt 3 Dateien zum Beispiel "max.c" (in ihr steht die vollständige Funktion/en) und "max.h" (in ihr wird die Schnittstelle der Funktion/en festgelegt) und mein Hauptquellcode in dem alles eingebunden werden soll. Im Hauptcode verwende ich am Anfang "#include max.h". Soweit so gut. Jetzt steht aber doch nirgends der Pfad bzw. der Dateiname der Datei "max.c" also weiß der Compiler bzw. Linker gar nicht wo die Datei zu finden ist und schon gar nicht was er anstellen soll wenn eine Funktion aus der Datei "max.c" aufgerufen wird.
Meine Frage ganz einfach: Woher weiß der Compiler bzw. Linker wie die Datei mit Funktionen, deren Schnittstellen in der Headerdatei festgelegt sind, heißt.
Sorry das ich das nicht so ganz verstehe bzw. die Frage falsch formuliert habe.
-
Steve0 schrieb:
Meine Frage ganz einfach: Woher weiß der Compiler bzw. Linker wie die Datei mit Funktionen, deren Schnittstellen in der Headerdatei festgelegt sind, heißt.
Garnicht, dass musst Du ihm schon mitteilen. Das heisst Du bindest neben dem Hauptprogramm auch die Datei max.c in Dein Projekt/Makefile/Compileraufruf ein, damit der Linker später neben dem Hauptprogramm auch die Implementierungen Deiner Funktionen findet.
Am einfachsten ist das wohl bei einer IDE mit Projektverwaltung. Bei einem manuellen Aufruf des GCC sähe das hingegen z.B. so aus:
g++ -c -o max.o max.cpp g++ -c -o main.o main.cpp g++ -o programm main.o max.ooder in einem Rutsch
g++ -o programm main.cpp max.cppEDIT: Hups, bin ja hier im C++ Board

-
Steve0 schrieb:
Meine Frage ganz einfach: Woher weiß der Compiler bzw. Linker wie die Datei mit Funktionen, deren Schnittstellen in der Headerdatei festgelegt sind, heißt.
Nein. Das Brauch er auch nicht wissen. Wissen muss es der Linker. Der weis es aber auch erst, wenn du es ihm sagst.
-
Meine Frage ganz einfach: Woher weiß der Compiler bzw. Linker wie die Datei mit Funktionen, deren Schnittstellen in der Headerdatei festgelegt sind, heißt.
"Compiler bzw. Linker"? Das ist dein Problem. Also: der Compiler muß nicht wissen wo welche Funktion/Klasse zu finden ist. Ihm reicht das er weiß, das es diese irgendwo gibt (deshalb reichen die Headerdateien!).
Der Linker bekommt gesagt, welche Objekt-Dateien (die der Compiler erzeugt hat) es gibt und er sucht sich aus diesen die Symbole raus, die er braucht.
Alle Dateien die verareitet werden sollen, müssen dem Compiler und Linker explizit angegeben werden, wenn sie aufgerufen werden. Wenn du z.B. VisualC++ benutzt, siehst du in der Konsole nur die Outputs vom Compiler und Linker. In wirklichkeit gibt die IDE natürlich jede CPP-Datei einzeln dem Compiler. Z.B. so:
cl.exe max.cppHier kompiliert der MSVC (der heißt cl.exe) die max.cpp und erzeugt eine max.obj Datei. Da steht der Maschinencode drin mit ein paar zus. Symbol-Infos.
link.exe /NOLOGO /SUBSYSTEM:WINDOWS /incremental:no /OUT:"meine-exe.exe" max.objDann wird danach der Linker aufgerufen, der bekommt als Parameter die max.obj Datei und sinnvollerweise noch eine Runtime-Library übergeben. Diese Dateien werden dann zu einer EXE verlinkt.
Wenn du mehrere CPP-Dateien in einem Projekt hast, kann man natürlich dem compiler und linker auch alle auf einmal übergeben. Aber man muß sie explizit angeben.
-
Danke an alle. Soweit hab ich das jetzt verstanden.