Die Vorgehensweise ist sehr einfach.
Du schreibst erst mal deinen C-Code. Zb fängst du an mit
FileA.C
1 | int VarExtA;
|
2 | int VarIntA;
|
3 |
|
4 | #define PortpinX PortA.1
|
5 |
|
6 | int functionIntA( void )
|
7 | {
|
8 | VarIntA = VarExtB;
|
9 | functionB();
|
10 | PortpinX = 1;
|
11 | };
|
Schau den Code durch. Damit du functionB aufrufen kannst, brauchst du
einen Prototypen. Der kommt aus einem Header File (das du noch nicht
hast), das aber FileB.h heissen wird. Also ergänzt du den Include
FileA.C
1 | #include "FileB.h"
|
2 |
|
3 | int VarExtA;
|
4 | int VarIntA;
|
5 |
|
6 | #define PortpinX PortA.1
|
7 |
|
8 | int functionA( void )
|
9 | {
|
10 | VarIntA = VarExtB;
|
11 | functionB();
|
12 | PortpinX = 1;
|
13 | };
|
So. Damit ist FileAch vollständig. Da fehlt jetzt erst mal nichts mehr.
Die Variable VarExtB wird ebenfalls über den include hereingezogen
werden.
Jetzt gehst du her und überlegst: Was von dem Zeugs in FileA.C soll wer
anderer verwenden können, welche Dinge muss FileA von sich preis geben.
Da sind zu erst mal die beiden Variablen. Was soll mit denen geschehen.
VarExtA soll von aussen zugreifbar sein, VarIntA nicht. Und dann
natürlich die Funktion, die aufrufbar sein soll.
Also schreibst du ein Header File für FileA.c , in das all das
reinkommt, was FileA.c nach aussen sichtbar machen will.
FileA.h
1 | extern int VarExtA;
|
2 |
|
3 | int functionA( void );
|
Die Variable kriegt ein extern davor, bei der Funktion nimmst du einfach
die Implementierung weg und machst einen ; dahinter. (und wenn du willst
kannst du auch extern davor schreiben, ist aber nicht notwendig)
Erneuter Blick aufs Header File. Kommt da irgendwas vor, was nicht
Standard C Schlüsselwort ist? Nein. Nichts.
Also ist dieses Header File vollständig.
Zur Sicherheit ergänzt du jetzt in FileA.c noch einen Include auf das
eigene Header File, denn dann kann der Compiler überprüfen ob die
Angaben im Header File mit der tatsächlichen Implementierung
übereinstimmen. Und da VarIntA von aussen nicht sichtbar sein soll (auch
nicht durch Tricks), wird sie static gemacht.
FileA.c
1 | #include "FileA.h"
|
2 | #include "FileB.h"
|
3 |
|
4 | int VarExtA;
|
5 | static int VarIntA;
|
6 |
|
7 | #define PortpinX PortA.1
|
8 |
|
9 | int functionA( void )
|
10 | {
|
11 | VarIntA = VarExtB;
|
12 | functionB();
|
13 | PortpinX = 1;
|
14 | };
|
Dasselbe für FileB.c. Erst mal einfach runterschreiben
1 | int VarExtB;
|
2 | int VarIntB;
|
3 |
|
4 | #define SettingB 0x01
|
5 |
|
6 | int functionB( void )
|
7 | {
|
8 | VarExtA = 1;
|
9 | functionA();
|
10 | VarIntB = SettingB;
|
11 | };
|
damit functionA aufgerufen werden kann, braucht es einen Prototyp. Den
kriegen wir von FileA.h
1 | #include "FileA.h"
|
2 |
|
3 | int VarExtB;
|
4 | int VarIntB;
|
5 |
|
6 | #define SettingB 0x01
|
7 |
|
8 | int functionB( void )
|
9 | {
|
10 | VarExtA = 1;
|
11 | functionA();
|
12 | VarIntB = SettingB;
|
13 | };
|
Was noch? Nix mehr. In FileB.c wird sonst nix mehr verwendet was nicht
entweder C Schlüsselwort oder im File selber oder durch einen include
rreinkommt.
Dann wieder: das Header File für B schreiben. Dabei einfach nur
überlegen: was soll von FileB.c nach aussen getragen werden.
FileB.h
1 | extern int VarExtB;
|
2 |
|
3 | int functionB( void );
|
und zur Sicherheit wieder ins eigene C-File includen und alle Variablen
(oder auch Funktionen), die von aussen nicht sichtbar sein sollen, als
static markieren.
FileB.c
1 | #include "FileB.h"
|
2 | #include "FileA.h"
|
3 |
|
4 | int VarExtB;
|
5 | static int VarIntB;
|
6 |
|
7 | #define SettingB 0x01
|
8 |
|
9 | int functionB( void )
|
10 | {
|
11 | VarExtA = 1;
|
12 | functionA();
|
13 | VarIntB = SettingB;
|
14 | };
|
damit bleibt nur noch main.c
Auch das schreiben wir erst mal einfach runter
1 | int c;
|
2 |
|
3 | int main()
|
4 | {
|
5 | functionA();
|
6 | functionB();
|
7 | VarExtA = 1;
|
8 | VarExtB = c;
|
9 | }
|
damit functionA aufgerufen werden kann, braucht es einen Prototypen.
Woher kommt er? Aus FileA.h. Also gleich mal includen
1 | #include "FileA.h"
|
2 |
|
3 | int c;
|
4 |
|
5 | int main()
|
6 | {
|
7 | functionA();
|
8 | functionB();
|
9 | VarExtA = 1;
|
10 | VarExtB = c;
|
11 | }
|
damit functionB aufgerufen werden kann, braucht es einen Prototypen. Wo
kommt er her? Aus FileB.h. Also noch ein include
1 | #include "FileA.h"
|
2 | #include "FileB.h"
|
3 |
|
4 | int c;
|
5 |
|
6 | int main()
|
7 | {
|
8 | functionA();
|
9 | functionB();
|
10 | VarExtA = 1;
|
11 | VarExtB = c;
|
12 | }
|
Fehlt noch was? VarExtA ist durch den include von FileA.h bereits
abgedeckt und VarExtB ist durch den include von FileB.h bereits
abgedeckt. Also fehlt nix mehr. Auch in main.c sind damit alle Sachen
abgedeckt und es ist in sich vollständig.
Compilieren, Linken, keine Fehler
(ausser der Tippfehler, die ich jetzt hier gemacht habe)
Das ist der Standardmechanismus.
Implementierung im C File schreiben
Überlegen, was von dieser Implementierung von aussen sichtbar sein soll.
Dasjenige kommt als Deklaration ins Header File, alles andere am besten
static machen.
Für alles im C-File, das seinerseits woanders herkommt, gibt es einen
include, der das jeweilig einbindet.
Und dann gibt es Sonderfälle und taktische Spielchen. Da kommt dann der
Link von oben ins Spiel. Aber bis dahin ist das alles ganz banales
Vorgehen nach Kochrezept.