Hallo NG, ich benutze WINAVR, und habe mein Testprogramm in mehrere Teile zerlegt: -main.c -lcd.c -v24.c MAIN benutzt Funktionen der beiden anderen C-Programme LCD und V24. Es funktioniert alles ganz prima, wenn ich die beiden C-Programme in MAIN direkt einbinde: - #include lcd.c - #include v24.c Da mir das so nicht gefällt, habe ich mir Header-Dateien - lcd.h - v24.h gebaut, in denen ich nur die von MAIN benutzten Funktionen aufgelistet habe. In MAIN binde ich dann die Headerdateien - #include "lcd.h" - #include "v24.h" ein. Bei jedem Aufruf einer Funktion von LCD oder V24, kommt aber jetzt die Fehlermeldung, dass die Funktion nicht definiert sei. Eigentlich sollte das Ganze doch so funktionieren, oder funktionieren Headerdateien nur zusammen mit den kompilierten C-Programmen. WFR
Wenn Du main.c compilierst, sollte keine Fehlermeldung kommen, wenn die *.h-Files mittels #include eingebunden sind und wirklich alle aufgerufenen Funktionen mit korrekten Prototypen dort vorgestellt werden. Wenn Du das ganze in etwas lauffähiges (bzw. flash-fähiges) überführen willst (mit dem Linker), dann mußt Du natürlich auch die entsprechenden Objektfiles zu den *.h-Files dazulinken. (Denn schließlich steht nur dort drin, wie die Funktionen was tun sollen. Im h-File steht ja nur, wie sie aufzurufen sind.) Du mußt also sowohl main.c als auch die beiden Files lcd.c und v24.c compilieren (d.h. in Object-Files überführen), damit Du sie dann alle zusammenlinken kannst. Gruß, Michael
Hallo Michael, genauso denke ich mir das auch, das es gehen sollte, trotzdem werkt das mir nicht. Aber lassen wir das Kompilieren der einzelnen C-Programme erst mal weg. Also ich habe jetzt ein ganz simples Beispiel 1. main.c #include "test.h" .
Hallo Michael, genauso denke ich mir das auch, das es gehen sollte, trotzdem werkt das bei mir nicht. Aber lassen wir das Kompilieren der einzelnen C-Programme erst mal weg. Also ich habe jetzt ein ganz simples Beispiel 1. main.c --------- #include "test.h" . . int main (void) { testInit(); } 2. test.c --------- void testInit (void) { } 3. test.h void testInit (void); Was mache ich denn da falsch? Sobald ich main kompiliere, kommt die Fehlermeldung: "undefined reference to `testInit'"
Hi, so gehts: 2. test.c --------- #include "test.h" . . void testInit (void) { } 3. test.h --------- extern void testInit (void);
Hi Werner, wie kompilierst Du das Ganze? Wenn Du das per makefile machst, musst Du test.c natürlich auch noch unter den Sourcen aufnehmen, z.B.: SRC = main.c test.c Damit sollte es aber klappen -- achja, hinter den #includes gehören auch nach die Semikolons (ist das die Mehrzahl von Semikolon??) Gruß, Oliver
Hallo Oliver, ich denke Semikolons und Semikola ist beides richtig. In meinem Makefile finde ich übrigens kein: SRC = .... siehe Anlage
Hallo Oliver, Noch ein Nachtrag. Die Zeile "SRC = ...." im Make File habe ich da nur probehalber einmal reingeschrieben. Sie ist ohne Wirkung. Werner
Hallo Werner, ich verwende das Standardmakefile, welches mit WinAVR geliefert wird (siehe Anhang), damit hatte ich bis jetzt keine Probleme. Dein makefile kann man sicher so erweitern, dass es auf Deine Anwendung passt, aber evtl. kannst Du ja auch mit dem Std-makefile glücklich werden... Dort gibt es übrigens den Eintrag SRC und wenn Du den anpasst, sollte es keine Probleme mehr geben. Für den Fall, dass Du test.h in einem anderen Pfad als die beiden .c-Sourcen hast, musst Du denn Pfad noch unter EXTRAINCDIRS spezifizieren. Oliver
In Deinem makefile werden alle Files compiliert und gelinkt, die unter OBJ aufgeführt sind. Ich bin mir nicht sicher ob es reicht, dort test.o aufzuführen...
Hallo Oliver, auch mein MakeFile war bei WinAvr dabei. Ich selber bin noch gar nicht in der Lage am MakeFile rumzumachen. Es reicht übrigens aus, wenn man "test.o" unter "OBJ" ergänzt. ##### Was ist denn deine Meinung, sollte ich lieber auf das "Standard-MakeFile" umsteigen? Werner
Hmm, das bleibt letzten Endes Deinem persönlichen Geschmack vorbehalten. Der Vorteil, den ich in dem von mir geposteten makefile (es stammt übrigens aus dem Verzeichnis /winAVR/sample) sehe, liegt einfach darin, dass es von vielen Leuten hier zumindest als Basis benutzt wird und Dir somit im Falle eines Falles schneller geholfen werden kann. Gruß, Oliver
Irrtümer schleicht euch ! Also ein paar Anmerkungen zu dem schon geäußerten : 1. Beim Aufteilen eines Projektes in mehrere Dateien (sehr löblich !) erweist es sich oft als praktisch die weiteren .c - Dateien entweder alle in ein Verzeichnis oder noch besser in verschiedene Verzeichnisse je nach Bedeutung abzulegen. Meinetwegen so : Hauptverzeichnis |- main.c |- (main.h) |- UART | |- UART.c | |- UART.h |- Display | |- display.c | |- display.h ... Der Vorteil dabei ist, wenn man mal ein anderes Projekt macht und Bausteine verwenden will, dann kann man ganz gut diese Bausteine herauskopieren und weiterverwenden. 2. #include <blablubb.h> bindet den Header blablubb.h aus dem Standardincludeverzeichnis (wo auch immer es ist) ein. #include <mehr/blablubb.h> bindet den header blablubb.h aus dem Unterverzeichnis mehr des Standardincludeverzeichnisses ein. #include "hallihallo.h" bindet den Header hallihallo.h aus dem Projektverzeichnis ein. #include "tolleHeader/meins.h" entsprechend für das Unterverzeichnis tolleHeader des Projektverzeichnisses. 3. nach #include .... kommt kein Semikolon ! die #include-Anweisung ist ein Präprozessorbefehl, der dem Compiler in der Textersetzungsphase mitteilt, an dieser Stelle eine Datei Buchstabe für Buchstabe einzukleben. 4. Mit dem Tool mFile und dem dazugehörigen Standardmakefile aus dem Lieferumfang von WinAVR kann man sehr einfach ein funktionierendes Makefile erstellen. Dazu wird das Standardmakefile in das Projektverzeichnis kopiert und anschließend mit dem Tool mFile komfortabel editiert. Wenn man dann noch Sonderwünsche hat, kann man das Makefile auch mit dem selben Tool von Hand weitereditieren. Dazu ein Hinweis an die Verwender von Versionshaltungssystemen mit checkin/checkout sowie beim Kopieren von ganzen Projekten : Das Tool mFile bindet die zusätzlichen .c-Dateien mit einem absoluten Pfad (d:/avr/meinTollesProjekt/meineGenialeSchnittstelle/dummy.c) ein. Wenn man das Projekt an eine andere Stelle kopiert oder mit einem Versionshaltungssystem in einen anderen Ordner auscheckt, stimmen die Pfade nicht mehr. Man sollte hier in diesem Falle per Hand auf relative Pfade zum Projektverzeichnis umstellen, wenn dies angezeigt erscheint. MfG, Daniel
HiHo! Zu 3: Stimmt - shame on me :( Zu 2: Anstatt den Pfad zu einem anderen Header direkt in die #include-Anweisung aufzunehmen, kann man die Pfade, in denen noch Headerdateien zu finden sind im makefile unter 'EXTRAINCDIRS = ' aufführen. Dadurch wird die bereits unter (1) angesprochene Portabilität der Module weiter unterstützt (Eine Änderung der Pfade bewirkt eine zentrale Änderung im makefile anstatt X Änderungen in den Sourcefiles (wenn der Header X-Mal includiert wird)). Im Prinzip ist aber auch dieses Geschmacksache. Gruß, Oliver
Hallo NG, Alsao ich habe jetzt alles auf das "Standard-MakeFile" umgestellt. Es funktioniert sogar ;-) Vielen Dank an alle für die Hilfe.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.