Verschachtelung von #includes

Hallo,

ich habe ein größeres Projekt mit vielen Dateien gemacht und bin fast fertig.

Dabei habe ich folgende Konstellation

File: Menu.h --> ruft eine Funktion auf, die in Uhr.h definiert wurde
File: Uhr.h --> ruft eine Funktion auf, die in Menu.h definiert wurde

Wenn ich jetzt zuerst

#definie Menu.h

einbinde, dann meckert er, dass die Funktion in Uhr.h nicht bekannt ist und umgekehrt.

Ich bräuchte eine Lösung, wo erst alles eingelesen wird und erst dann auf Fehler geprüft wird...

Macht das Einbinden nicht #include?

Hast du für jede .h auch eine .cpp ?

.h sind Header Dateien, und keine Funktionen!

Nein, habe leider (aus Unwissenheit) alles in die .h Dateien gepackt...

Ich nutze die Arduino Sprache. Wie wäre es denn richtig? So?

main.ino:

#include "Test.h"

File Test.h:

#define Konstante blabla
void Test1();
...

File Test.cpp:

void Test1(){

blablabla
}

Code bitte in Code Tags.

Arduino hat keine eigene Sprache. Es nennt sich C. Evtl auch C++....

Dein Beispiel ist vom Prinzip schon mal ganz ok.
Jetzt kommt es noch auf die Umsetzung an.

Deine Bib braucht noch #ifndef gegen "doppeltes inkludieren". Schau mal z.B. in fertigen Bibs nach...

#ifndef

#pragma once

Ist auch voll ok.
Der alte Include Guard ist eher von historischem Interesse. Und unhandlich, ist er.

Danke und add!

Werde das bei mir änden.

Kreisförmige Abhängigkeiten sollte man nach Möglichkeit vermeiden.

Abgesehen davon dass du wie gesagt die Deklaration von der Implementierung trennen musst (getrennte .h und .cpp Dateien) sind hier Lösungen für Funktionen und Klassen gezeigt:

Ich baue gerade meinen ganze Code um und kriege nun die Fehlermeldung:

'byte' does not name a type

Was habe ich jetzt kaputt gemacht, dass er die Klasse byte nicht mehr kennt?
Noch zur Info (mit geänderten Namen):

main.h - ok (dort kennt er byte)
main.ino - ok
sub.h - nok - hier kennt er das byte nicht mehr
sub.c - soweit kommt er nicht :slight_smile:

Byte ist keine Klasse! Das ist ein Arduino typedef auf unsigned char. Wenn du dass wo anders verwenden willst musst du Arduino.h inkludieren.

Also das funktioniert und ich mache große (Lern)fortschritte.

Jetzt passiert noch etwas, was ich gar nicht verstehe:

Ich deklariere im Main.h:

#define BUZZERPIN 11

dann nutze ich im Buzzer.cpp diesen Pin:

pinMode(BUZZERPIN, OUTPUT);

Dann sagt er, dass im Buzzer.cpp dieser Pin nicht deklariert wurde.
Stimmt auch, habe ich ja schon im Main.h deklariert und dieser wurde als erstes inkludiert.

Wenn ich jetzt (nur versuchsweise) im Buzzer.cpp #include "Main.h" mache, dann geht es trotzdem nicht...
Das verstehe ich überhaupt nicht. Danke für eure Geduld.

AAAAAA. Habs gefunden.
Habe statt

#ifndef BUZZER_H

#ifdef BUZZER_H

geschrieben :slight_smile:

Nun dauert es relativ lange und es bleibt alles fehlerfrei

und dann kommen hundertausende von Fehlern wie:

sketch\Buzzer.cpp.o (symbol from plugin): In function `ts':

(.text+0x0): multiple definition of `ts'

sketch\Buttons.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\Buzzer.cpp.o (symbol from plugin): In function `ts':

(.text+0x0): multiple definition of `LCD_RESET'

sketch\Buttons.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\Buzzer.cpp.o (symbol from plugin): In function `ts':

(.text+0x0): multiple definition of `tft'

sketch\Buttons.cpp.o (symbol from plugin):(.text+0x0): first defined here

sketch\Buzzer.cpp.o (symbol from plugin): In function `ts':

(.text+0x0): multiple definition of `p'

usw.

Für mich sieht das aus, wie wenn es Mehrfachdeklarationen gab. Aber genau das habe ich doch über #ifndef vermeiden wollen...

Da hilft nur zippen und hochladen. Oder per pn...

Noch besser wäre ein verkürztes aber komplettes Beispiel, so wie dieses (das funktioniert allerdings):

--- Main.h ---

#ifndef _MAIN_H_
#define _MAIN_H_

#define BUZZER_PIN 11
void init();
void test_function();

#endif

--- Buzzer.cpp ---

#include <Arduino.h>
#include "Main.h"
void init() {
   Serial.begin(9600);
   pinMode(BUZZER_PIN, OUTPUT);
}
void test_function() {
   Serial.println("Test");
}

--- Test.ino ---

#include "Main.h"
void setup() {
   init();
   test_function();
}
void loop() {}

Das ist allerdings so einfach, dass der Titel "Verschachtelung von includes" nicht ganz passt...

Michael, sollte deine Buzzer.cpp nicht Main.cpp sein??
Warum verwendest du #pragma once nicht?

Der Titel "Sketch mit mehreren Tabs richtig erstellen" wäre evtl. besser.

@dost, am besten wäre ein "Minimalbeispiel". So nennt man das zumindest in anderen Foren. Aber dein Code ist auch so sicherlich schnell repariert.

Michael, sollte deine Buzzer.cpp nicht Main.cpp sein??

???
nöö...

Tipp:
Niemals *.cpp in *.cpp Dateien einbinden.

Warum verwendest du #pragma once nicht?

Das kann ich dir nicht sagen, warum er das nicht verwendet.

Aber, er verwendet einen Include Guard!
Und damit ist die Sache gut genug.

Aha :o

In der Main.h sind die Funktionsdeklarationen von der Buzzer.cpp?
Ist das so richtig?

Ich dachte für eine Main.h (Header) müsste eine Main.cpp (Code) bestehen!?

mde110:
In der Main.h sind die Funktionsdeklarationen von der Buzzer.cpp?
Ist das so richtig?

Ja, das finde ich auch nicht schön....

Es ist in sofern richtig, als dass es funktioniert und nicht verboten ist.
Mehr aber auch nicht......

Ich dachte für eine Main.h (Header) müsste eine Main.cpp (Code) bestehen!?

Wenn, dann, wird da andersrum ein Schuh draus.

Zu einer *.cpp, sollte es auch eine *.h geben.
*.h können auch als einsame Krieger existieren.

Hallo,
ja ich werde ein Minimalbeispiel erstellen und hochladen.

Vorher habe ich aber noch eine Frage, weil ich denke, dass ich fast fertig bin.

Ich habe jetzt also alles schön aufgeteilt in .h und .cpp Dateien.

Das Ding kompiliert, aber es gibt Linkerfehler.

Mein Verdacht:

Ich habe z.b. eine Hilfsroutine.c und .h

die .h Datei inkludiere ich aus Menu.c UND Zeit.c. Darf man das?

Das .h File sieht z.B. so aus:

#ifndef HILFSROUTINEN_H
#define HILSROUTINEN_H

void Hilfsfunktion();

#endif

Warum meckert der Linker?

z.B.

In file included from C:\Users\dos2si\Documents\Arduino\libraries\SPFD5408-master\SPFD5408_Adafruit_TFTLCD.cpp:30:0:

C:\Users\dos2si\Documents\Arduino\libraries\SPFD5408-master\pin_magic.h:306:33: warning: backslash and newline separated by space

   #define read8inline(result) { \    

 ^

sketch\Buzzer.cpp.o (symbol from plugin): In function `beep(int, int)':

(.text+0x0): multiple definition of `Zahl_Endzeit'

sketch\Buttons.cpp.o (symbol from plugin):(.text+0x0): first defined here