Headerdatei definieren, kenne mich nicht aus

OP #2365865
Lesenswert?

Hallo zusammen,

ich beschäftige mich als Anfänger gerade damit Code in externen Dateien 
richtig in das Hauptprogramm einzubinden.  AVRStudio 5 Atmega 32

Konkret möchte ich die lcd_tools_2.2.c Datei richtig ins Hauptprogramm 
einbinden.
Bisher habe ich diese Datei includiert und es funktionierte!! Ich habe 
hier im Forum gelesen, das das aber nicht der richtige Weg ist und 
deswegen möchte ich jetzt lernen es richtig zu machen.

Ich habe eine Headerdatei angelegt mit den Definitionen  und den 
Funktionsprototypen aus der LCD_tools Datei.

In der Headerdatei habe ich auch den LCD_Port definiert (#define 
LCD_Port PORTB), dennoch bekomme ich eine Fehlermeldung diesbezüglich 
siehe Bild.

Die externe lcd_tools_datei Datei habe ich folgendermaßen eingebunden. 
siehe Bild


Würdet ihr mir bitte helfen, denn die diversen Dokumentationen habe ich 
noch nicht so richtig verstanden.
http://www.mikrocontroller.net/articles/FAQ#Ich_hab_da_mehrere_.2A.c_und_.2A.h_Dateien._Was_mache_ich_damit.3F

Deswegen habe ich meine Dateien rein gestellt wie weit ich gekommen bin 
und wo ich nicht mehr weiter weiß.

Herzlichsten Dank im voraus,

Matthias.
Angehängte Dateien:
Gast #2365948
Lesenswert?

Das hier kann so auch nicht funktionieren
1
#include "E:\Eigene Dateien\Dropbox\Atmel AVR\AVR Programme\1aVorlagen\lcd_tools_h.h"

eerstmal müssten die Ordnerer Trennzeichen so
1
#include "E:/Eigene Dateien/Dropbox/Atmel AVR/AVR Programme/1aVorlagen/lcd_tools_h.h"
oder so
1
#include "E:\\Eigene Dateien\\Dropbox\\Atmel AVR\\AVR Programme\\1aVorlagen\\lcd_tools_h.h"
aussehen.

Und die Leerzeichen in dem Pfad sind auch nicht gerade vorteilhaft.
OP #2365972
Lesenswert?

Hallo zusammen,

leider klappt es immer noch nicht und ich weiß nicht wieso. Es kann dann 
nicht so schwer sein.

Ich verstehe es so:

als 3. wird die Datei lcd_tools_h.h includiert

und somit auch #define LCD_Port PORTB   festgelegt

dann wird der Code von lcd_tools_2.2.c hinzugefügt

dann dürfte doch keine Fehlermeldung LCD_PORT undeclared first use in 
this function mehr kommen oder was verstehe ich das noch nicht?

Ich versuche mir die grundsätzliche Vorgehensweise zu erarbeiten wie man 
Code aus anderen Dateien ins Hauptprogramm hinzufügt.

Wärt ihr so nett und helft mir weiter?

Herzlichste Grüße,

Matthias.
Angehängte Dateien:
Gast #2366016
Lesenswert?

PS.:
lcd_tools.h auch in die lcd_tools.c einbinden, sonst ist LCD_PORT nicht 
definiert.

Außerdem solltest du dir angewöhnen, eine Header so aufzubauen:
1
#ifndef LCD_TOOLS_H
2
#define LCD_TOOLS_H
3
//eigentlicher Inhalt
4

5
#endif

So wird beim ersten Mal inkludieren ein Compilerschalter gesetzt (am 
besten den Dateinamen wie oben gezeigt), und bei weiteren Inkludierungen 
wird die Datei nicht nochmal beachtet.
Verhindert also Mehrfachdefinitionen.
:-)
Gast #2366101
Lesenswert?

Wenn du in lcd_tools_2.2.c definitionen aus lcd_tools_h.h und io.h musst 
du die header natürlich auch einbinden.

Wenn du in header abc.h eine definition xyz hast, musst du sie auch in 
jeder quelldatei einbinden, in der du diese definition verwenden willst.
OP #2366139
Lesenswert?

Hallo,

jetzt habe ich es hoffentlich nach Euren Hinweisen gemacht. Dennoch ist 
eine Fehlermeldung übrig und ich weiß nicht wieso.


Auch habe ich diese SAche nicht verstanden:

Außerdem solltest du dir angewöhnen, eine Header so aufzubauen:

#ifndef LCD_TOOLS_H
#define LCD_TOOLS_H
//eigentlicher Inhalt

#endif

So wird beim ersten Mal inkludieren ein Compilerschalter gesetzt (am
besten den Dateinamen wie oben gezeigt), und bei weiteren Inkludierungen
wird die Datei nicht nochmal beachtet.
Verhindert also Mehrfachdefinitionen.

warum soll ich das definieren? ich habe die Headerdatei doch über 
#include eingebunden.
Was bringt das dies zu definieren und in welcher Datei soll das stehen?

Viele Grüße,

Matthias.
Angehängte Dateien:
Gast #2366148
Lesenswert?

Matthias H. schrieb:
> Was bringt das dies zu definieren und in welcher Datei soll das stehen?

Folgendes Szenario:

du hast eine funktion int foo(). Diese ist in einer Datei foo.c 
implementiert.
Dazu schreibst du noch eine Headerdatei (foo.h), die die Signatur der 
Funktion enthält.

Jetzt benötigst du die Funktion foo() in main.c und in anderswo.c
Also musst du die foo.h überall dort einbinden, wo die Deklaration 
bekannt sein muss.
Jetzt gibts aber plötzlich 2 Signaturen zur Funktion foo()
Um das zu vermeiden, wird beim Aufruf der Datei abgefragt, ob sie schon 
bekannt ist (ifndef = if not defined), falls nicht, mach sie bekannt 
(define) und lese sie durch. Ansonsten kommt man direkt zum Ende und tut 
nix (endif).

Für solche Sachen sollte man aber mal ein C-Buch lesen ;-)
Moderator Persönliche Seite #2369374
Lesenswert?

Floh schrieb:
> Jetzt gibts aber plötzlich 2 Signaturen zur Funktion foo()

Nein.  Du kannst die Funktion foo() so häufig deklarieren, wie du
nur möchtest.  Dabei darfst du optional noch das Schlüsselwort
"extern" voranstellen, um zu kennzeichnen, dass dies nur eine
Deklaration ist, die den Compiler über die Funktion informiert.

Wofür man dieses #ifdef (im Englischen typischerweise "idempotence"
genannt) jedoch braucht ist, wenn im Headerfile noch weitere Dinge
definiert oder deklariert werden, bei denen ein mehrfaches Auftreten
innerhalb einer Übersetzungseinheit nicht wünschenswert oder nicht
zulässig ist.  Erstgenannter Fall trifft auf #defines zu, wenn
während eines Übersetzungsgangs sowas auftritt
1
#define FOO 42
2
#define FOO 42

dann ist das zwar zulässig, aber kann je nach Compiler durchaus eine
Warnung produzieren.  Schlimmer wird es jedoch mit
1
enum foo {
2
  A, B, C
3
};
4
...
5
enum foo {
6
  A, B, C
7
};

Hier wird die zweite Definition von enum foo vom Compiler abgelehnt.

Warum kann es nun überhaupt dazu kommen, dass man das zweimal hat?
Ganz einfach: Headerfiles sollte für sich immer "self contained"
sein, d. h. sie ziehen sich alle nötigen `prerequisites' vorab
mit rein.  Man kann nun zwei Headers haben a.h und b.h, die jeweils
aus diesem Grunde c.h mit #includen, weil sie einen Teil der
Definitionen und Deklarationen aus c.h benötigen.  Wenn nun main.c
sowohl a.h als auch b.h selbst benötigt, dann wird auf diese Weise
c.h zweimal verarbeitet.  Mit dem #ifdef kümmert man sich darum,
dass es beim zweiten #include (egal, welches von beiden das zweite
ist) keinerlei Inhalt mehr generiert.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren