Forum: Mikrocontroller und Digitale Elektronik völlig verwirrt von include und headerfiles


von Erik (Gast)


Lesenswert?

Tag!

Ich krieg's trotz lesen aller Threads zum Thema nicht hin, ein c-Projekt 
in mehrere Unterprogramme aufzuteilen. Ich fürchte, ich brauch's noch 
mal zum mitmeißeln...
Ich benutze AVRStudio in C (GCC).

Beispiel:
Ich habe ein Programm, wir nennen es "main.c". Im gleichen Verzeichnis 
liegt der code für Subroutinen "lcd.c". Jetzt möchte ich Funktionen aus 
lcd.c in main.c aufrufen, weil ich nicht den ganzen Code in der main.c 
haben möchte. Da erkennt man ja irgendwann nichts mehr. Also habe ich 
eine lcd.h Headerdatei geschrieben, die NUR die Funktionsprototypen aus 
der lcd.c enthält, sonst nichts, keine includes, kein garnix.
Lässt sich nicht compilieren und ich werd noch mal blöd :)

Bsp:

main.c
=======
#include <avr/io.h>
#include "lcd.h"
int main (void)
{
unterfunktion(123);
return 1;
}

lcd.h
========
void unterfunktion(char uebergabewert);

lcd.c
=========
#include<avr/io.h>

void unterfunktion(char uebergabewert)
{
uebergabewert=uebergabewert*2;
}

_________________________________________________

a) Warum lässt sich das nicht kompilieren?

Und noch ein paar Fragen:
b) Muss die Datei lcd.c auch im Makefile unter SRC angegeben werden? 
Wenn ja, mit oder ohne ".c" und wie getrennt von "main" (komma 
semikolon...)
c) Stehen im header nur funktionsprototypen oder kann da auch code 
drinstehen?
d) Muss der Prototyp von "unterfunktion" AUCH in lcd.c stehen?
e) Müssen alle drei Files im AVRstudio im "SourceFiles" und 
"HeaderFiles"- Ordner sein?

Ihr würdet einem verzweifelten Mann einen großen Gefallen tun...

Erik

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Gegenfrage:

Was heißt "lässt sich nicht kompilieren"? Ich kenne keinen C-Compiler, 
der DAS als Fehlermeldung ausgibt.

a) kann daher nicht beantwortet werden.

b) Ja, im Makefile muss jedes einzelne Modul (== C-Source-File) 
aufgeführt werden, aus dem das Programm sich zusammensetzen soll.

c) Nur Funktionsprototypen, #defines und extern-Deklarationen von 
Variablen, auf die von anderen Modulen aus zugegriffen werden soll 
(globale Variablen) sowie Typdeklarationen (enum, struct, union & 
typedef), sofern diese von mehreren Modulen genutzt werden sollen.

d) Nein, lcd.c sollte allerdings lcd.h einbinden.

e) Nein, die Dateien gehören in das Verzeichnis (Ordner), das Du für 
Dein Projekt angelegt hast.

von Karl H. (kbuchegg)


Angehängte Dateien:

Lesenswert?

> Ich benutze AVRStudio in C (GCC).

OK.

Zu mitmeiseln:

Ich öffne AVRStudio und lege eine neues Projekt an.
Dann kopiere ich dein main.c auf das Projektverzeichnis.
DIe lcd.h und lcd.c könnte ich auch dorthin kopieren, tu
ich aber nicht, da die ja das Zeug für eine allgemeine
Bibliothek haben. Also leg ich mir dafür einen Ordner
an (C:\AVRLib) und kopiere die Dateien dorthin.

Damit habe ich die Situation:

Projektverzeichnis: main.c
C:\AVRLib : lcd.h, lcd.c

Das *.c File, dass mir AVRStudio generiert hat, nehme
ich aus dem Projekt raus (weil ich ja von dir ein main.c
gekriegt habe): Im Projekt-Baum das File mit der rechten
Maustaste anklicken und "Remove File from Project"

Dein main.c muss ich noch etwas abändern, weil ja lcd.h
nicht auf dem Projektverzeichnis liegt, sondern auf C:\AVCLib

Das sieht jetzt so aus
1
#include <avr/io.h>
2
#include "C:\AvrLib\lcd.h"
3
4
int main (void)
5
{
6
unterfunktion(123);
7
return 1;
8
}

main.c ist damit fertig und kann zum Projekt hinzugefügt
werden:
Im Projektbaum mit der rechten Maustaste auf "Source Files"
klicken. "Ass existing source File(s)" und anschliessend zeige
ich dem AVRSTudio die main.c

Jetzt muss noch lcd.c zum Projekt hinzugefügt werden:

Im Projektbaum mit der rechten Maustaste auf "Source Files"
klicken. "Add existing source File(s)" und dem AVRStudio die
lcd.c auf C:\AVRLib gezeigt.

Weil ich gründlich bin, mache ich das Ganze nochmal mit der
lcd.h, diesmal allerdings im Abschnitt "Header Files"

Das Ganze sieht dann so aus, wie im angehängten Bild.

Ich drücke auf F7 um das Projekt bauen zu lassen.
Und voila: alles erledigt

main.c wurde compiliert
lcd.c wurde compiliert

main.o + lcd.o wurden zu einem fertigen Programm zusammengelinkt


von Erik (nicht der von oben :-)) (Gast)


Lesenswert?

Hallo,

Es könnte auch daran liegen, dass er die lcd.h in mehreren 
Programmteilen nutzt.
> lcd.h
> ========
> void unterfunktion(char uebergabewert);
Ich vermisse dann da irgendwie noch ein
1
extern
 vor dem Prototyp, sonst meckert der Compiler evtl. auch wenn ich lcd.h 
in mehreren Files inkludiere.

von holger (Gast)


Lesenswert?

dafür macht man doch
#ifndef BLA.h
#define BLA.h

HEADER

#endif


Das mit dem extern is doch nur nen unschöner hack in diesem 
Zusammenhang!

von peter (Gast)


Lesenswert?

Der GCC kann echt pingelig sein mit der Gross/Kleinschreibung  von 
Dateinamen. (Stammt halt aus der Linux, bzw. UNIX Welt)

"LCD.H" ≠"LCD.h" ≠"Lcd.H" ≠"Lcd.h" ≠ "lcd.h" ≠"lcd.H"

Ich hatte diesbezüglich auch schon Probleme, es lohnt sich die 
Gross/Kleinschreibung konsequent konsistent zu halten.

=> Dateinamen
=> Projekt Datei-Bezeichnungen (g.g.f. Anpassen)
=> Include Dateinamen

MfG  Peter

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Funktionsprototypen brauchen kein "extern", das ist implizit. Ganz im 
Gegensatz zu Variablendeklarationen.

von Mike R. (thesealion)


Lesenswert?

Und als letztes noch daran denken, das der Linker die Dateien auch noch 
alle kennen muß.

Evtl. Muß die lcd.c noch zu dem Projekt hinzugefügt werden, damit sie 
auch kompiliert wird.

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
Noch kein Account? Hier anmelden.