Geschweifte Klammer in Präprozessor Anweisung

Hallo Zusammen,

trotz längerer suche finde ich keine Antwort auf folgende Fragestellung.
Wie geht man mit geschweiften Klammern um, die in einer Präprozessoranweisung geöffnet werden, aber außerhalb geschlossen werden?

Beispiel:

#if defined(ESP8266)
while (Serial.available()) {
    byte received_byte = (byte)Serial.read();
#elif defined(ESP32)
while (customSerial.available()) {
    byte received_byte = (byte)customSerial.read();
#endif

//do something

}

...wirft beim kompilieren Fehler aus. Angeblich fehlt eine schließende geschweifte Klammer

#if defined(ESP8266)
while (Serial.available()) {
    byte received_byte = (byte)Serial.read();
#elif defined(ESP32)
while (customSerial.available()) {
    byte received_byte = (byte)customSerial.read();
#endif

//do something

}
}

...funktioniert, obwohl es in meinen Augen falsch ist. Der Präprozessor geht ja nur in eine der beiden Anweisung und sollte auch nur eine öffnende geschweifte Klammer sehen.

Wie ist denn die richtige Syntax, bzw wie geht ihr damit um?

Danke schon mal.

Hallo zeppelin500

Hier kommt was zum Lesen.

https://de.wikibooks.org/wiki/C-Programmierung:_Präprozessor

Wenn weder ESP8266 noch ESP32 definiert sind, ist ihr Code nicht korrekt.

In dem wir sowas nicht tun.....
(zumindest für mich gilt das)

In deinem Fall würde ich wohl versuchen konsequent auf Stream setzen.
Wobei:
Dein verstümmeltes Code Fragment ist nicht testbar.

Danke, aber da steht ja nichts dazu. Oder bin ich blind? Grundsätzlich ist es aber schon das, was ich suche --> was zum lesen :slight_smile:

Ja, dass ist Absicht. Das Projekt unterstützt explizit nur 2 Boards und ist mit noch weiterer Hardware verbunden.

Aber wenn Sie kompilieren, sind Sie sicher, dass einer der beiden definiert ist? Andernfalls generiert der Präprozessor nichts, und Sie haben nur die schließende geschweifte Klammer, was ein Fehler ist.

Danke!

JA, der Code ist recht lang :slight_smile:

Link

Hier der Link zum Projekt. Der Codeschnippsel befindet sich in der mbus.h

Stream sagt mir nichts, gibts da was zu lesen oder ein Beispiel?

Ja, bin ich sicher. Es ist nur für 2 verschiedene Boards vorgesehen. Zusätzlich verwenden eh alle nur die bereitgestellte .bin. Aber, ich möchte es halt einigermaßen sauber machen.

Das kompiliert.

Sie haben wahrscheinlich noch etwas anderes, das ein Problem verursacht. Posten Sie einen vollständigen Sketch, der zeigt, was Sie sagen.

Beispiel:

void mbus_short_frame(byte address, byte C_field) {
  byte data[6];

  data[0] = 0x10;
  data[1] = C_field;
  data[2] = address;
  data[3] = data[1] + data[2];
  data[4] = 0x16;
  data[5] = '\0';
  #if defined(ESP8266)
  Serial.write((char *)data,5);
  #elif defined(ESP32)
  MbusSerial.write((char *)data,5);
  #endif
}

Ein feste Abhängigkeit, welche dann noch per define ausgewählt wird....
Nicht schön!

evtl besser:

void mbus_short_frame(byte address, byte C_field, Stream &stream) {
  byte data[6];

  data[0] = 0x10;
  data[1] = C_field;
  data[2] = address;
  data[3] = data[1] + data[2];
  data[4] = 0x16;
  data[5] = '\0';
  stream.write((char *)data,5);
}

Die Abhängigkeit ist jetzt in der Parameterliste, wo sie auch hingehört.
#defines entsorgt.
Zudem: Funktionen in *.h Dateien werden dir noch Probleme bereiten.

Ja, so hab ich es ja umgesetzt, es funktioniert ja auch. Ich bin nur wegen was Anderem den Code durchgegangen und hab mich gewundert, dass es so funktioniert.

Danke
Leider hab ich den Stream noch nicht verstanden. Wo ist denn bei deiner Lösung definiert, welche "art" von Serial er verwenden soll?

Der von dir zitierte Codeschnipsel war, wie vieles andere, irgendwo gefunden und auf meine Bedürfnisse angepasst. Später dann um den ESP32 erweitert. Ich weiß, muss noch viel sauber machen, läuft aber hervorragend.

Gar nicht!
Das ist ja der Trick!
Beim Aufruf der Funktion übergibst du den richtigen Stream

Es ist nicht Aufgabe der Funktion den Stream auszuwählen.
Ist es doch gerade die Auswahl in der Funktion die dir Probleme bereitet.

Es reicht wenn man die Auswahl einmal vornimmt und nicht an Tausend Stellen im Code.

Das sind die Probleme von Codeschnipseln. Die 2. geschweifte Klammer im Beispiel von @J-M-L gehört zum setup, und hat mit deinem Präprozessor Konstrukt gar nichts zu tun. Das scheint bei dir dasselbe zu sein:

Da gehört die 2. geschweifte Klammer offensichtlich auch zu einer weiter oben stehenden dazu, die man in deinem Schnipsel nicht sieht.

Du hast es geknackt, das war die Lösung!
Das Problem war gar nicht die Klammer, sondern die Darstellung in der IDE. Er markiert ja immer die öffnende Klammer wenn ich eine Schließende anklicke. Und mit der Klammer in der Präprozessordirektive kommt dieses Hervorhebewerkzeug nicht klar. Er hat mir also nur die falsche öffnende Klammer markiert und es war von Anfang an alles richtig. Danke

Trotzdem, das mit dem Stream würde mich interessieren. Wo gibts denn da was "einfaches" zu lesen?

Klar, die IDE weis nichts vom Präprozessor ..
Deshalb ist es sehr unübersichtlich, mit den #ifdefs Code-Blöcke zu zerhacken. ( Obwohl ich das auch schon gemacht habe ... :roll_eyes: )

Mag sein, dass es manchen zu einfach ist, aber die Arduino Referenz kennst du?

:slight_smile: ja.

5 allgemein gehaltene Zeilen reichen zumindest mir nicht um das Thema zu verstehen. Mein Wunsch war eher so ein bisschen Erklärung und mehrere Beispiele.

Da steht, genau das was man wissen muss.
Beachte das runde Dutzend Links.

Da du Serial bedienen kannst, kannst du auch Stream bedienen

Aufruf:

mbus_short_frame(1,2, Serial) ;

Oder:

Stream &s = Serial;
mbus_short_frame(1,2, s) ;