Hallo Forum,
wer kann mit bezüglich Programmierung in C und insbesondere Arduino auf
die Sprünge helfen?
Ich habe folgendes Problem, bei dem ich ein bestehendes ESP8266 Projekt
auf meine Bedürfnisse abändern muss. In dem Projekt, welches in seinem
Ausgangszustand erfolgreich kompiliert, gibt es eine Datei Namens
store.h
// If config files dont match, save defaults then erase the ESP config to clear away any residue
102
}else{
103
eepromSave();
104
delay(500);
105
106
ESP.eraseConfig();
107
while(1);
108
}
109
}
110
111
#endif
Wie ihr sehen könnt, sorgt diese store.h Datei im wesentlichen für zwei
Dinge. Zum einen gibt es ein paar Funktionen, die EEPROM Zugriffe
umsetzten. Dann gibt es noch eine Struktur, die Programmparameter
speichert und welche auch gleich in der store.h initialisiert und mit
default Werten geladen wird. Genau diese Programmparameter aus der
Struktur benötige ich nun an anderer Stelle im Quelltext als der Main
Datei. Und das will nicht klappen.
1. Problem:
Ich inkludiere die Store.h in einer weiteren Quelltext Datei. Nun
meckert Arduino an, dass die Funktion eeprom.read nicht bekannt sei. Nun
diese entstammt der Arduino eigenen EEPROM.h und wird in der Store.h
auch wirklich nicht inkludiert. Fügt man
Die source.ino ist die Hautdatei des ganzen Programmes und dort werden
sowohl die EEPROM.h als Header als auch die Store.h bislang eingebunden.
Ich verstehe nur nicht, warum ich die store.h nicht auch noch woanders
einbinden kann. Das ist doch der Sinn von Headern und eigentlich sollten
so doch auch Klassen und Strukturen im Programm überall bekannt gemacht
werden können.
Jemand eine Idee, wie man diese bestimmt sehr triviale Problematik
richtig auflösen kann?
Deklaration von Typen, Variablen und Funktionen sind in .h richtig. Die
Definition von Variablen (also mit Inhalt, implizit oder explizit)
hingegen nicht, ebensowenig Funktionsdefinitionen, weil:
multiple definition of `deviceSettings'
multiple definition of `eepromLoad()'
Chris K. schrieb:> Wie ihr sehen könnt, sorgt diese store.h Datei im wesentlichen für zwei> Dinge. Zum einen gibt es ein paar Funktionen, die EEPROM Zugriffe> umsetzten. Dann gibt es noch eine Struktur, die Programmparameter> speichert und welche auch gleich in der store.h initialisiert und mit> default Werten geladen wird.
Und genau das ist Scheiße und gegen alle Regeln der C Programmierung.
Man trennt Deklarationen von Strukturen, makros und Typedefs von der
Implementation.
Die Deklaration in ein .h file, die Implementation in ein .c File, das
dann einmal compiliert und zu dem Projekt dazugelinkt wird.
Besorge die ein C Buch und arbeite es von vorne durch. Alles andere wird
nix.
Chris K. schrieb:> Struc as header einbinden - Compiler dreht durch
Nein, er dreht nicht durch sondern er meldet dir einfach
dass du dich nicht an die Regeln hältst.
Und das ist gut so. Es hilft dir dein Unwissen und Chaos
zu bewältigen.
Gut,
ich sehe ein, dass der Compiler es nicht mag, wenn die gesamte Funktion
im Header definiert wird und dann der Header an mehreren Stellen
eingebunden wird. Hilft mir jetzt aber leider auch nicht dabei weiter
das Problem zu lösen, dass der ursprüngliche Verfasser des Quelltextes
eingebaut hat.
Die erste Baustelle ist also die store.h aufzuräumen, damit die
Definition aus der Header Datei verschwindet.
Naiver Ansatz also:
// If config files dont match, save defaults then erase the ESP config to clear away any residue
73
}else{
74
eepromSave();
75
delay(500);
76
77
ESP.eraseConfig();
78
while(1);
79
}
80
}
Ist aber auch blöd, weil es so die Deklaration der Struktur 2 mal gibt
und das macht ja eigentlich auch keinen Sinn. Aber wie muss die store.c
aussehen, wenn dort der Konstruktor für die Struktur sein soll?
> Ist aber auch blöd, weil es so die Deklaration der Struktur 2 mal gibt
Dann lass es halt sein! Im .c-File ist sie unnötig, gar falsch ;-)
Ins .c-File einfach nur nen
// If config files dont match, save defaults then erase the ESP config to clear away any residue
59
}else{
60
eepromSave();
61
delay(500);
62
63
ESP.eraseConfig();
64
while(1);
65
}
66
}
nun meckert der Compiler zurecht, dass er die "variable" IPAdresse in
der Struktur nicht auflösen kann. Muss auch wieder sowas Adurino
spezifisches sein. Scheinbar wird die in der Header Datei ESP8266WiFi.h
beschrieben. Diese ist in der Main auch inkludiert. Will ich die
zusätzlich in der Store.h mit einbinden erhält man folgenden Fehler
...AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libra
ries\ESP8266WiFi\src/ESP8266WiFiGeneric.h:27:22: fatal error:
functional: No such file or directory
#include <functional>
Argh... als Programmieranfänger kann einen so etwas wirklich dazu
bringen in die Tischkante zu beißen. Warum hat er denn keine Probleme
mit dem Inkludieren in der Main Datei, aber in einer anderen Header
Datei?
Chris K. schrieb:> Danke foobar,> habe die Dateien umgebaut und kotze schon wieder im Strahl:>> store.h>> ifndef store_h> #define store_h
wie wäre es mit # vor ifndef?
Chris K. schrieb:> Argh... als Programmieranfänger kann einen so etwas wirklich dazu> bringen in die Tischkante zu beißen.
Nein, du hast soeben eine Situation erlebt die dir die
Macher des Arduino-Environments eingebrockt haben.
Chris K. schrieb:> und kotze schon wieder im Strahl
Dagegen hilft Vomex oder ein gutes C-Buch.
Allerdings letzteres nicht einnehmen sondern geistig inhalieren.
Du musst die Konzepte verstehen, sonst wird das nix, sorry aber
programmieren in C ist nix für "maker".
Du kannst das Problem "lösen", indem du das chaotische Headerfile nur
genau ein Mal #include-ierst. Schön wird es deswegen trotzdem nicht.
Variablen gehören allenfalls mit "extern" in ein Headerfile (Ausnahme:
inline).
Die fehlenden Funktionsexports musst du dir dann über ein anderes
Headerfile exportieren.
Chris K. schrieb:> Hilft mir jetzt aber leider auch nicht dabei weiter> das Problem zu lösen, dass der ursprüngliche Verfasser des Quelltextes> eingebaut hat.
Und was hindert dich dran, das Problem auszubauen? Du hast den gesamten
Quelltext doch vor dir. Also teile die Datei in eine Header- und eine
Sourcedatei auf, und alles wird gut.
Oliver