Hallo ich versuche gerade meinen Code auszulagern. Es geht um ein .c file in dem sich Funktionen wiederfinden. Im Hauptfile wird diese ausgelagerte mit #include "ReadTemp.c" aufgerufen. Ich bin mir nicht sicher aber ich glaube alle benötigten include müssen im ausgelagerten .c file auch noch stehen weil der eine von dem anderen vor dem linken nichts voneinander weiß stimmt das so ? Leider wirft mir Atmel Studio aber dennoch Fehler raus.... " ReadTemp.c:In function 'SensorRead' ReadTemp.c:7:2: error: 'Heitzung_Temp' undeclared (first use in this function) ReadTemp.c:each undeclared identifier is reported only once for each function it appears in Error compiling " Kann mir dabei wer helfen ? Gruß
Hier scheint so einiges durcheinander zu gehen. Erstmal included man keine .c Dateien sondern nur .h Header. Schreibe also eine entsprechende Headerdatei für deine ReadTemp.c Datei mit Deklarationen aller Funktionen. Woher die Fehlermeldung kommt kann ich jetzt auch nicht herausfinden. Aber es ist sicher kein Linkerfehler. Den Linker interessiert es überhaupt nicht welche Header du eingebunden hast. Der Compilerfehler deutet aber auf eine fehlenden Header hin.
:
Bearbeitet durch User
Für Klassen ect. habe ich das natürlich so umgesetzt und die .h Datei includiert. Bei einfachen Funktionen wollte ich mir das sparen. Aber das müsste doch so funktionieren oder nicht ?
Nein du kannst nicht einfach .c Dateien includen. Theoretisch kopiert ein include ja nur den Dateiinhalt an die entsprechende Stelle wo das #include stand. Wenn du das mit .c Dateien machst wird Atmel Studio aber wohl auf die Idee kommen die ReadTemp.c genauso zu compilieren wie deine main.c und wenn alles Ende gelinked wird gibts einen Linkerfehler wegen doppelt definierter Funktionen. Wenn man doch mal eben schnell eine Funktion in eine extra Datein auslagern will und kein .c/h. Paar erstellen will dann macht man nur eine .h Datei und definiert alle Funktionen als inline. Aber niemals nur eine .c Datei.
@ Indi (Gast) >Für Klassen ect. habe ich das natürlich so umgesetzt und die .h Datei >includiert. Klassen, soso. Du bist also so fit und wissend, dass du C++ beherrschst, nur bei den elementaren C-Grundlagen hapert es ein wenig? >Bei einfachen Funktionen wollte ich mir das sparen. >Aber das müsste doch so funktionieren oder nicht ? Nö. Da werden dann "lustig" mehrere Funktionen mit gleichem Namen erzeugt und der Linker ist leicht irritiert. Mach es einfach richtig und ordentlich. Es werden AUSSCHLIELICH .h Datein per #include eingebunden, welche die Headerinfos der Funktionen der zugehörogen .c Dateien enthalten. "Der preiswerteste und schnellste Weg etwas zu tun ist, es gleich richtig zu tun." (Hab ich heute wieder mal gelernt 8-0)
Indi schrieb: > Für Klassen ect. habe ich das natürlich so umgesetzt und die .h Datei > includiert. > Bei einfachen Funktionen wollte ich mir das sparen. > Aber das müsste doch so funktionieren oder nicht ? Im Prinzip ja. Aber wahrscheinlich vermutest du da wieder mal irgendeine Wunderwuzzi Funktionalität hinter dem #include. Ein #include ist eine ganz einfache Sache: Er wird vom Präprozessor bearbeitet, der an dieser Stelle im Code ganz einfach den Inhalt der angegebenen Datei einsetzt. Und erst das Ergebnis dieser Ersetzung geht dann an den eigentlichen Compiler. Ein #include ist nicht mehr als eine reine Textverarbeitungssache. Mehr passiert dabei nicht. Hast du Code in einer Datei main.c
1 | void foo() |
2 | {
|
3 | mach was; |
4 | }
|
5 | |
6 | void bar() |
7 | {
|
8 | mach was anderes; |
9 | foo(); |
10 | }
|
11 | |
12 | int main() |
13 | {
|
14 | bar(); |
15 | }
|
und lagerst du die Funktion bar in eine eigene Datei bar.inc aus (ich nenn das absichtlich nicht bar.c, eben weil hier die Funktion selbst drinnen steht, die Datei aber nicht eigenständig compiliert werden soll), dann hast du in main.c
1 | void foo() |
2 | {
|
3 | mach was; |
4 | }
|
5 | |
6 | #include "bar.inc" |
7 | |
8 | int main() |
9 | {
|
10 | bar(); |
11 | }
|
und bar.inc
1 | void bar() |
2 | {
|
3 | mach was anderes; |
4 | foo(); |
5 | }
|
Der Präprozessort schnappt sich die main.c und stösst irgendwann auf das
1 | ...
|
2 | #include "bar.inc" |
3 | ...
|
das ist für ihn das Signal, diese Zeile rauszuwerfen und durch den Inhalt der Datei bar.inc zu ersetzen. D.h. der Präprozessor führt die beiden Einzelteile zusammen und erhält als Ergebnis den Text
1 | void foo() |
2 | {
|
3 | mach was; |
4 | }
|
5 | |
6 | void bar() |
7 | {
|
8 | mach was anderes; |
9 | foo(); |
10 | }
|
11 | |
12 | int main() |
13 | {
|
14 | bar(); |
15 | }
|
den er dann an den eigentlichen C Compiler weiter gibt. Alles bestens. Hast du das main.c aber so aufgebaut
1 | #include "bar.inc" |
2 | |
3 | void foo() |
4 | {
|
5 | mach was; |
6 | }
|
7 | |
8 | int main() |
9 | {
|
10 | bar(); |
11 | }
|
dann führt die Text-Einsetzung logischerweise zu
1 | void bar() |
2 | {
|
3 | mach was anderes; |
4 | foo(); |
5 | }
|
6 | |
7 | void foo() |
8 | {
|
9 | mach was; |
10 | }
|
11 | |
12 | int main() |
13 | {
|
14 | bar(); |
15 | }
|
und wenn wir uns das ansehen, dann sehen wir, dass von oben nach unten gelesen aus bar heraus eine Funktion foo() aufgerufen wird, von der zum 'Zeitpunkt' des Aufrufs noch nichts bekannt ist, weil sie ja im Endergebnis unter der Funktion bar steht ohne dass es einen Prototypen dafür gab. Und dann gibt es eben von deinem Compiler eine entsprechende Warnung bzw. Error. Fazit: ein #include ermöglicht dir, Einzelteile deines Codes auf mehrere Dateien aufzuteilen, die in Textform vom Präprozessor wieder zusammengesetzt werden, ehe das so erhaltene Machwerk dann zum Compiler geht. Wie du diese Aufteilung machst, ist deine Sache. Das interessiert weder den Präprozessor noch den Compiler. Nur muss nach dem Präprozessor gültiger C Code rauskommen. Und ja: die übliche Form ist es, Funktionen in getrennt compilierbare C-Files zu stecken, für die man dann ein Header File schreibt, welches includiert wird. Dieses Vorgehen hat sich bewährt, auch wenn es nicht vorgeschrieben ist und es durchaus auch Abweichungen davon geben kann und gibt. Aber grundsätzlich kann man den Präprozessor einfach nur als eine Art Texteditor ansehen, der deinen Quelltext bearbeitet, ehe dann das erhaltene Machwerk zum Compiler geht. Sinnigerweise stehen die Anweisungen an diesen Texteditor im Text, den dieser spezielle Editor bearbeitet. Aber recht viel mehr steckt da nicht dahinter.
:
Bearbeitet durch User
Indi schrieb: > Du hattest recht, mit der .h funktionierts . Gruß Okay es geht doch nicht, ich war zu schnell mit der Antwort .h " #include "TempRead.h" void TempRead() { Pool_Temp.requestTemperatures(); Heitzung_Temp.requestTemperatures(); } " .c " // TempRead.h #ifndef _TEMPREAD_h #define _TEMPREAD_h #include "arduino.h" //-------SourceFile------------ #include "OneWire.h" // One Wire Source #include "DallasTemperature.h" // Dallas Temperatur Source für One Wire Sensor DS18s20 void TempRead(); #endif " Das ist hier alles was ich bisher habe
Indi schrieb:
Wenn wir uns nur und ausschliesslich dieses C++ File ansehen
1 | #include "TempRead.h" |
2 | |
3 | void TempRead() { |
4 | |
5 | Pool_Temp.requestTemperatures(); |
6 | Heitzung_Temp.requestTemperatures(); |
7 | }
|
wer oder was ist "Pool_Temp"? Wer oder was ist "Heitzung_Temp"? Jedes C-File (oder bei dir eben C++ File) wird für sich alleine compiliert und muss für sich alleine gesehen vollständig sein!
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.