Eigene Bibliotheken/Headerdateien erstellen / externe Funktion?!
-
Hallo,
ich hoffe zum erstmal, dass der Titel einigermaßen richtig gewählt ist
Zu meinem Problem: ich möchte eine selbst geschriebene Funktion einfach mit#include <meineFunktion.h>
in meine Programme einbinden. Dafür muss ich ja eine eigene Bibliothek für diese Funktion anlegen. Nur wie geh ich da jetzt vor?! Ich habe zwar einiges dazu gefunden, aber irgendwie bin ich jetzt verwirrt.
wenn ich beispielsweise folgende Funktion
void cb(void) { int c=0; while ( (c=getchar() ) != EOF && c != '\n') ; }
über
#include cb.h
in einem beliebigen Programm einbinden will um nur noch z.B.
... cb(); ...
schreiben zu müssen, wie müsste ich jetzt vorgehen? Vielleicht so:
Headerdatei:
/* cb.h*/ extern void cb(void);
Datei cb.c:
#include "cb.h" void cb(void) { int c=0; while ( (c=getchar() ) != EOF && c != '\n') ; }
Aber hätte ich das ganze jetzt nicht einfach nur Modularisiert?! Oder ist das genau das was ich will... Ich bin grad irgendwie verwirrt, vielleicht schmeiße ich auch einfach nur irgendwelche Begriffe durcheinander....Ich hoffe, ihr könnt mir weiterhelfen! Vielen Dank im voraus!
Grüße
-
Wenn du deinen Code auf mehrere Dateien aufteilen willst, kannst du das so machen:
// cb.h void cb(void);
// cb.c #include "cb.h" void cb(void) { int c=0; while ( (c=getchar() ) != EOF && c != '\n') ; }
// main.c #include "cb.h" int main(void) { // Irgend was cb(); // Mehr Code }
Das musst du dann alles zusammen kompilieren / linken. Ist das das was du willst? Sonst einfach nochmal nachfragen
Edit: In cb.h moechtest du vermutlich noch einen #include guard ( http://en.wikipedia.org/wiki/Include_guard ) einfuegen.
-
Erstmal herzlichen Dank für die schnelle Antwort!
Ich habe mir das halt so vorgestellt, dass ich einmal eine Funktion schreibe und die dann in beliebige Programme einbinden kann, wie meine stdlib.h oder stdio.h usw. und die dann wie printf und co nutzen kann.
Kann ich das Problemlos mit dem was du geschrieben hast machen, oder wie ist der elegante Weg? Dein Beispiel ist doch eigentlich nur die Modularisierung des Codes, oder?Grüße
-
chmbw schrieb:
Aber hätte ich das ganze jetzt nicht einfach nur Modularisiert?!
Genau. Aber was ist eine Bibliothek anderes, als ein Modul, das irgendwelche Schnittstellen anbietet?
Deine Datei cb.c ist eine Übersetzungeinheit, d.h. du kannst sie für sich alleine in eine Objektdatei (.o, .obj, oder so) übersetzen. Diese Objektdatei kann man dann statisch gegen eine zweite linken, in der die main-Funktion ist, man erhält eine ausführbare Datei. Dazu kann man deinen Code ohne Änderung verwenden (du solltest vermutlich noch include guards in dem Header machen). Dann ist der Code von cb.c in der ausführbaren Datei enthalten.
Die meisten Systeme bieten noch eine ganz andere Art von Objektdateien an, nämlich solche, gegen die man dynamisch linken kann (.so, .dll oder so). Wenn man so etwas verwendet, ist der Code von cb.c in einer eigenen Datei, und kann von mehreren ausführbaren Dateien verwendet werden.
Wie du deinem Compiler sagen kannst, was davon du haben willst, können dir sicher die Leute im Compiler-Forum erklären.
Edit: Grammatik
-
chmbw schrieb:
Ich habe mir das halt so vorgestellt, dass ich einmal eine Funktion schreibe und die dann in beliebige Programme einbinden kann, wie meine stdlib.h oder stdio.h usw. und die dann wie printf und co nutzen kann.
Dabei kann man leicht übersehen, dass auch der Code der Funktionen, die in den Standard-Headern deklariert werden, irgendwie verlinkt werden muss. Die C-Laufzeit-Bibliothek ist recht klein, so dass es auf grossen Maschinen nicht weiter auffällt, wenn man das statisch verlinkt. Aber der Code muss verlinkt werden, weil sonst der Linker mit einem Namen wie printf() nichts anfangen kann.
-
alles klar, sprich ich mach es am besten so wie lustig es beschrieben hat und speicher mir mein cb.h bzw. cb.c einfach in einem bestimmten Ordner und binde sie dann immer entsprechend mit #include verzeichnis/cb.h ein. Danke euch!
-
chmbw schrieb:
alles klar, sprich ich mach es am besten so wie lustig es beschrieben hat und speicher mir mein cb.h bzw. cb.c einfach in einem bestimmten Ordner und binde sie dann immer entsprechend mit #include verzeichnis/cb.h ein.
Das klingt, als wolltest du cb.c jedesmal neu übersetzen lassen. Das ist gar nicht notwendig (deshalb gibt es die Objektdateien). Mach eine Bibliothek aus cb.c, dann brauchst du nur mehr die Bibliothek-Datei und den Header.
Du kannst leicht vereinfachend davon ausgehen, dass zwischen Bibliotheken und Objektdateien kein Unterschied besteht. Worum es gerade geht, ist, ob du statisch oder dynamisch linken willst, und ob du cb.c jedesmal neu übersetzen willst (wovon ich abrate).
-
ich muss gestehen mit dynamischen linken habe ich mich NOCH nicht wirklich intensiv auseinander gesetzt...
cb.c jedesmal neu zu übersetzen ist ja irgendwie sinnbefreit...
mngbd schrieb:
Mach eine Bibliothek aus cb.c, dann brauchst du nur mehr die Bibliothek-Datei und den Header.
auch wenn ich mir bei der Frage ein wenig doof vorkomme...wie genau soll ich das machen?!
-
Das koennen wir dir nur sagen, wenn du uns wenigstens dein Betriebssystem angibst... und den Compiler ;).
-
chmbw schrieb:
ich muss gestehen mit dynamischen linken habe ich mich NOCH nicht wirklich intensiv auseinander gesetzt...
Du kannst den Code cb.c ja auch statisch verlinken. Das macht sicherlich kaum einen Unterschied, solange es nur so wenig Code ist. Dynamisches Linken muss im Vergleich dazu noch Rücksicht auf das System nehmen.
chmbw schrieb:
auch wenn ich mir bei der Frage ein wenig doof vorkomme...wie genau soll ich das machen?!
Finde zuerst einmal heraus, wie man auf deinem System eine Bibliothek aus einer Objektdatei macht (das sollte nicht schwer sein). Dann leg diese Datei irgendwo ab, zum Testen vielleicht in das Verzeichnis, in dem die Standard-Bibliotheken des Compilers leben. Dann sollte der Rest ganz einfach sein.
Mach am besten einen neuen Thread im Compiler-Forum, wenn du spezielle Fragen zu System und Compiler hast.
-
Vielleicht willst du noch ein wenig auf Wikipedia lesen:
http://en.wikipedia.org/wiki/Object_file
http://en.wikipedia.org/wiki/Library_(software)wäre ein guter Anfang.
-
ich benutze momentan Windows 7 64bit und als compiler die akutelle Version von Code::Blocks.
-
chmbw schrieb:
ich benutze momentan Windows 7 64bit und als compiler die akutelle Version von Code::Blocks.
Code::Blocks ist kein Compiler sondern eine IDE. Vemutluch verwendest du den gcc Compiler für Windows.
-
chmbw schrieb:
ich benutze momentan Windows 7 64bit und als compiler die akutelle Version von Code::Blocks.
Na dann rtm, oder:
http://www.adp-gmbh.ch/cpp/gcc/create_lib.htmlUnd ab ins Compiler-Forum.
-
vielen dank, dann weiß ich jetzt wo ich nachschlagen / fragen muss etc
-
ich hab jetzt nochmal ein wenig damit rumgespielt,aber jetzt folgendes Problem:
ich habe eine headerdatei cb.h:
extern void cb(void);
und eine Datei cb.c
#include "cb.h" #include <stdio.h> void cb(void) { int c=0; while ( (c=getchar()) != EOF && c != '\n'); }
#include <stdio.h> #include <stdlib.h> #include "C:/Users/Michael/CodeBlocks/Projekte/cbtest/cb.h" int main() { char a, b; printf("Bitte Buchstaben eingeben\n"); scanf("%c",&a); cb(); printf("2.Buchstabe\n"); scanf("%c",&b); cb(); printf("\n1.=%c 2.=%c\n\n",a,b); return 0; }
wenn ich jetzt die Datei cb.c mit ins Projekt einbeziehe, dann klappts, aber auch wenn ich die Headerdatei cb.h nicht mit einbeziehe. Wenn die Datei nicht im Projekt mit dabei ist, meckert er, dass er cb nicht kennt...müsste das aber nicht theoretisch trotzdem gehen? Ich als Compiler GNU-CC und als IDE CodeBlocks. Vielen Dank im Voraus!
-
chmbw schrieb:
wenn ich jetzt die Datei cb.c mit ins Projekt einbeziehe, dann klappts, aber auch wenn ich die Headerdatei cb.h nicht mit einbeziehe. Wenn die Datei nicht im Projekt mit dabei ist, meckert er, dass er cb nicht kennt...
Leg den Header in ein globales Include-Verzeichnis. Und mach endlich include guards!
-
zu befehl^^
edit: globales include-verzeichnis = verzeichnis wo auch sdtio.h usw liegen?!
edit2:
jetzt mit include guards:
#ifndef CB_H_INCLUDED #define CB_H_INCLUDED extern void cb(void); #endif // CB_H_INCLUDED
-
chmbw schrieb:
zu befehl^^
Wäre halt eine gute Idee.
chmbw schrieb:
edit: globales include-verzeichnis = verzeichnis wo auch sdtio.h usw liegen?!
Das ist eines davon. Man kann die Verzeichnisse global über eine Umgebungsvariable einstellen (INCLUDE_PATH oder so ähnlich), oder über einen Schalter beim Aufruf des Compilers.
Edit:
Wenn du die include guards nicht machst, kann es mühsam werden, sobald einige Header einander zyklisch #includen. Dann müsstest du dir jedes mal über die Reihenfolge den Kopf zerbrechen. Wenn du sie machst, lösen sich solche Probleme ganz von selbst.
-
da fällt mir noch eine Frage ein:
ich binde in cb.c ja noch stdio.h ein weil er sonst meckert...so binde ich die aber doch auch doppelt ein?! Dafür müsste ich dann doch auch noch einen Guard basteln?!