Class in Class

Moin,

Um meinen Code übersichtlicher zu gestalten möchte ich alle “Nebenfunktionen” und Hintergrundaufgaben (WiFi- / MQTT-Verbindung aufbauen, Config-Server und AccessPoint verwalten, Config sichern FS / json)
soweit wie möglich in eigene Librarys bzw. Klassen auslagern.

Im Sketch soll dann nur noch ein #include Hauptklasse stehen.

Es soll eine Hauptklasse für die WiFi-Verbindungen geben.
Die Hauptklasse soll dann aber auch auf eine ServerKlasse zugriff haben.

.h (Hauptklasse)

#include <ServerKlasse.h> 

#include <alle anderen benötigten Klassen>

Wenn ich jetzt in der Serverklasse eine bereits in der Hauptklasse benötigte Library benötige deklariere ich diese mit #ifndef
.h (ServerKlasse)

#ifndef ESP8266WebServer_h
#define ESP8266WebServer_h
#ifndef ESP8266WiFi_h
#define ESP8266WiFi_h
#ifndef WiFiClient_h
#define WiFiClient_h

...
...
...


#endif
#endif
#endif

Das funktioniert auch soweit, ist das so aber auch richtig?

Ich habe nämlich das Problem, das in der ServerKlasse ein einfaches Serial.println("");
nicht mehr geht?

.cpp

#include <ESP8266_Basic_webServer.h>

ESP8266_Basic_webServer::ESP8266_Basic_webServer(){
}

void ESP8266_Basic_webServer::pp(){
  Serial.println("");
}

Fehlermeldung:

C:\Users\Admin\Documents\Arduino\libraries\ESP8266_Basic\ESP8266_Basic_webServer.cpp: In member function ‘void ESP8266_Basic_webServer::pp()’:

C:\Users\Admin\Documents\Arduino\libraries\ESP8266_Basic\ESP8266_Basic_webServer.cpp:11:3: error: ‘Serial’ was not declared in this scope

Serial.println("");

^

exit status 1
Fehler beim Kompilieren.

Für Tips wäre ich dankbar.

Gruß
Pf@nne

Pfanne: Für Tips wäre ich dankbar.

Ich habe nur den Beginn Deines Postings gelesen und musste sofort an abgeleitete Klassen denken (Stichwort Vererbung). Vielleicht ist das, was Du suchst.

Gruß

Gregor

Damit Serial geht musst du #include "Arduino.h" machen. Wie soll das sonst bekannt sein?

ifndef ESP8266WebServer_h

define ESP8266WebServer_h

ifndef ESP8266WiFi_h

define ESP8266WiFi_h

ifndef WiFiClient_h

define WiFiClient_h

Das sieht irgendwie nicht richtig aus. Das mit #ifndef #define in Headern sind Include Guards um Mehrfach Inkludierungen zu verhindern: https://de.wikipedia.org/wiki/Include-Guard

Damit zeigt man an dass ein Header schon inkludiert wurde. Beim ersten mal wird das #define Makro gesetzt. Beim nächsten mal ist es schon bekannt und der Code wird nicht übersetzt.

Moin,

Serenifly: Damit Serial geht musst du #include "Arduino.h" machen. Wie soll das sonst bekannt sein?

OK, läuft..... aber woher weiß denn mein Sketch was Serial ist?

Serenifly: Das sieht irgendwie nicht richtig aus. Das mit #ifndef #define in Headern sind Include Guards um Mehrfach Inkludierungen zu verhindern:

Das ist doch aber genau das, was ich erreichen will. Ich brauche z.B die "ESP8266WebServer_h" sowohl in der .h (Hauptklasse) als auch in der .h (ServerKlasse).

Die Serverklasse wird in der Hauptklasse inkludiert. Daher wäre es doch in der Serverklasse ein doppelter Aufruf. Diesen vermeide ich doch mit dem #ifndef oder bin ich da falsch unterwegs.

Die "#pragma once" Variante scheint Arduino auch zu können, das müsste ich dann ja aber in den genutzten Klassen nachpflegen. Das wäre dann ja nach einem Update wieder weg.... ::)

OK, läuft..... aber woher weiß denn mein Sketch was Serial ist?

Die Arduino Software macht das alles im Hintergrund

Das ist doch aber genau das, was ich erreichen will. Ich brauche z.B die "ESP8266WebServer_h" sowohl in der .h (Hauptklasse) als auch in der .h (ServerKlasse).

Vielleicht hast du das auch abgekürzt, aber #ifndef bezieht sich auf den aktuellen Header in dem man gerade ist. Nicht auf die Header die man inkludiert.

Also wenn du einen Header Namens Test.h hast machst du:

#ifndef TEST_H
#define TEST_H

...

#endif

Serenifly: Also wenn du einen Header Namens Test.h hast machst du dort:

#ifndef TEST_H
#define TEST_H
...
#endif

Gruß

Gregor

Ja. Das auch. Im Header. Und woanders macht man einfach #include

include bedeutet ja nur dass der Text aus dem Header an die Stelle kopiert wird. Aber durch die Include Guards wird das dann nur einmal übersetzt.

Vielleicht hast du das auch abgekürzt, aber #ifndef bezieht sich auf den aktuellen Header in dem man gerade ist. Nicht auf die Header die man inkludiert.

Ahh....OK, dann macht mein Quatsch nun wirklich keinen Sinn.

Wie kann ich denn jetzt in meinen beiden Klassen (Hauptklasse und Serverklasse) auf ein und die selbe Library / Klasse zuzugreifen?

Habe ich doch gesagt:

Und woanders macht man einfach #include

Also immer nur #include machen wenn du was einbinden willst

#include <WiFiClient.h> 
#include <ESP8266WiFi.h>			//https://github.com/esp8266/Arduino	
#include <EEPROM.h>

Mit diesen Librarys geht das nur nicht mit der, die ich brauche…

Wenn ich diese mit

#include "ESP8266WebServer.h"
oder 
#include <ESP8266WebServer.h>

in meine Serverklasse einbinde hagelt es Fehlermeldungen:

In file included from C:\Users\Admin\Documents\Arduino\libraries\ESP8266_Basic/ESP8266_Basic_webServer.h:3:0,

from C:\Users\Admin\Documents\Arduino\libraries\ESP8266_Basic\ESP8266_Basic_webServer.cpp:1:

C:\Users\Admin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.1.0-rc2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:63:30: error: expected ‘)’ before ‘addr’

ESP8266WebServer(IPAddress addr, int port = 80);

^

C:\Users\Admin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.1.0-rc2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:87:3: error: ‘WiFiClient’ does not name a type

WiFiClient client() { return _currentClient; }

^

C:\Users\Admin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.1.0-rc2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:134:22: error: ‘WiFiClient’ has not been declared

bool _parseRequest(WiFiClient& client);

^

C:\Users\Admin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.1.0-rc2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:137:19: error: ‘WiFiClient’ has not been declared

bool _parseForm(WiFiClient& client, String boundary, uint32_t len);

^

C:\Users\Admin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.1.0-rc2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:140:27: error: ‘WiFiClient’ has not been declared

uint8_t _uploadReadByte(WiFiClient& client);

^

C:\Users\Admin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.1.0-rc2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:150:3: error: ‘WiFiServer’ does not name a type

WiFiServer _server;

^

C:\Users\Admin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.1.0-rc2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:152:3: error: ‘WiFiClient’ does not name a type

WiFiClient _currentClient;

^

C:\Users\Admin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.1.0-rc2\libraries\ESP8266WebServer\src/ESP8266WebServer.h: In member function ‘size_t ESP8266WebServer::streamFile(T&, const String&)’:

C:\Users\Admin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.1.0-rc2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:128:10: error: ‘_currentClient’ was not declared in this scope

return _currentClient.write(file, HTTP_DOWNLOAD_UNIT_SIZE);

^

exit status 1
Fehler beim Kompilieren.

Dann hast du offensichtlich etwas falsch gemacht und Klassen wie WiFiClient und WiFiServer sind sind in dem Header nicht bekannt

Serenifly:
Dann hast du offensichtlich etwas falsch gemacht

Da hast du wohl wieder recht…

<ESP8266WebServer.h> braucht <ESP8266WiFi.h>

und wie immer:

kaum macht man es richtig, schon klappt es…