Kreuzinclude löst Fehlermeldung aus

Hi,

ich bin gerade meine Libraries am schreiben und generiere einen speziellen Fehler.

Ich habe eine Klasse A welche Klasse B included. Klasse A beinhaltet eine Ref variable auf Klasse B.

Im Prozess ruft dann Klasse A eine Funktion in Klasse B auf.

Jetzt braucht jedoch Klasse B ein paar Variablen aus Klasse A. Mein Plan war es hier auch eine Ref Variable auf Klasse A zu erstellen. Damit ist sichergestellt das ich flexibel auf Daten zugreifen kann und diese nicht im Funktionskopf hinterlegen muss.

Wenn ich jedoch in der Klasse B meine Klasse A include (Um die Ref Variable erstellen zu können), bekomme ich plötzlich ein Compilererrir in Klasse A das meine Klasse B nicht gefunden werden kann.

Hier ein Auszuf der .h Struktur:

[color=#d4d4d4][color=#c586c0]#ifndef[/color][color=#569cd6] WifiProvider_h[/color]
[color=#c586c0]#define[/color][color=#569cd6] [/color][color=#569cd6]WifiProvider_h[/color]

[color=#c586c0]#include[/color][color=#569cd6] [/color][color=#ce9178]<WiFi.h>[/color]
[color=#c586c0]#include[/color][color=#569cd6] [/color][color=#ce9178]<esp_wifi.h>[/color]
[color=#c586c0]#include[/color][color=#569cd6] [/color][color=#ce9178]<NVMProvider.h>[/color]
[color=#c586c0]#include[/color][color=#569cd6] [/color][color=#ce9178]<GPSProvider.h>[/color]
[color=#c586c0]#include[/color][color=#569cd6] [/color][color=#ce9178]<ESPmDNS.h>[/color]
[color=#c586c0]#include[/color][color=#569cd6] [/color][color=#ce9178]"WebServerProvider.h"[/color]


[color=#c586c0]#define[/color][color=#569cd6] [/color][color=#569cd6]NMEA_TCP_PORT[/color][color=#569cd6] [/color][color=#b5cea8]1818[/color]

[color=#c586c0]#ifdef[/color][color=#569cd6] [/color][color=#569cd6]UPTIME[/color]
[color=#c586c0]#include[/color][color=#569cd6] [/color][color=#ce9178]"uptime_formatter.h"[/color]
[color=#c586c0]#endif[/color]

[color=#569cd6]class[/color] [color=#4ec9b0]WifiProvider[/color]
{
[color=#569cd6]public:[/color]
    [color=#dcdcaa]WifiProvider[/color]();
    [color=#569cd6]void[/color] [color=#dcdcaa]init[/color]([color=#4ec9b0]stored_preference_t[/color] [color=#569cd6]*[/color][color=#9cdcfe]storedPreferences[/color], [color=#4ec9b0]WebServerProvider[/color] [color=#569cd6]*[/color][color=#9cdcfe]webServerProvider[/color]); 
    [color=#569cd6]void[/color] [color=#dcdcaa]setHostname[/color]([color=#569cd6]const[/color] [color=#569cd6]char[/color] [color=#569cd6]*[/color][color=#9cdcfe]hostname[/color]);
    [color=#569cd6]void[/color] [color=#dcdcaa]wifi_AP[/color]();
    [color=#569cd6]void[/color] [color=#dcdcaa]wifi_STA[/color]();
    [color=#569cd6]void[/color] [color=#dcdcaa]nmeaServerStart[/color]();
    [color=#569cd6]void[/color] [color=#dcdcaa]nmeaServerStop[/color]();
    [color=#569cd6]void[/color] [color=#dcdcaa]webConfigStart[/color]();
    [color=#569cd6]void[/color] [color=#dcdcaa]webConfigStop[/color]();
    [color=#4ec9b0]stored_preference_t[/color] *[color=#9cdcfe]stored_preferences[/color];
    [color=#4ec9b0]WebServerProvider[/color] *[color=#9cdcfe]webServer_provider[/color];
    [color=#4ec9b0]WiFiServer[/color] *[color=#9cdcfe]nmea_server[/color];
    [color=#4ec9b0]IPAddress[/color] [color=#9cdcfe]MyIP[/color];

    [color=#569cd6]char[/color] [color=#9cdcfe]ap_ssid[/color][[color=#569cd6]MAX_AP_NAME_SIZE[/color]];
    [color=#569cd6]const[/color] [color=#569cd6]char[/color] [color=#9cdcfe]ap_password[/color][[color=#569cd6]WIFI_KEY_MAXLEN[/color]] = VEDEX_PW;
    [color=#569cd6]const[/color] [color=#4ec9b0]uint[/color] [color=#9cdcfe]nmeaServerPort[/color] = NMEA_TCP_PORT;
    [color=#569cd6]bool[/color] [color=#9cdcfe]wifi_connected[/color] = [color=#569cd6]false[/color];

    [color=#4ec9b0]WiFiClient[/color] [color=#9cdcfe]NMEARemoteClient[/color];
[color=#569cd6]private:[/color]
};
[color=#c586c0]#endif
[/color][/color]
[color=#d4d4d4][color=#c586c0]#ifndef[/color][color=#569cd6] WEBSERVER_h[/color]
[color=#c586c0]#define[/color][color=#569cd6] [/color][color=#569cd6]WEBSERVER_h[/color]

[color=#c586c0]#include[/color][color=#569cd6] [/color][color=#ce9178]<WebServer.h>[/color]
[color=#c586c0]#include[/color][color=#569cd6] [/color][color=#ce9178]<ESPmDNS.h>[/color]
[color=#c586c0]#include[/color][color=#569cd6] [/color][color=#ce9178]<NVMProvider.h>[/color]
[color=#6a9955]//#include <WifiProvider.h>[/color]

[color=#c586c0]#include[/color][color=#569cd6] [/color][color=#ce9178]<uri/UriBraces.h>[/color]
[color=#c586c0]#include[/color][color=#569cd6] [/color][color=#ce9178]<Pagecontent/Header.h>[/color]
[color=#c586c0]#include[/color][color=#569cd6] [/color][color=#ce9178]<Pagecontent/Footer.h>[/color]
[color=#c586c0]#include[/color][color=#569cd6] [/color][color=#ce9178]<Pagecontent/css.h>[/color]
[color=#c586c0]#include[/color][color=#569cd6] [/color][color=#ce9178]<Pagecontent/root_options.h>[/color]

[color=#c586c0]#define[/color][color=#569cd6] [/color][color=#569cd6]WEBPORTAL_HEADER_DYN_SIZE[/color][color=#569cd6] [/color][color=#b5cea8]150[/color]

[color=#569cd6]class[/color] [color=#4ec9b0]WebServerProvider[/color]
{
[color=#569cd6]public:[/color]
    [color=#dcdcaa]WebServerProvider[/color]();
    
    [color=#569cd6]void[/color] [color=#dcdcaa]wsStart[/color]();
    [color=#569cd6]void[/color] [color=#dcdcaa]wsStop[/color]();
    [color=#569cd6]void[/color] [color=#dcdcaa]setStoredPreferences[/color]([color=#4ec9b0]stored_preference_t[/color] [color=#569cd6]*[/color][color=#9cdcfe]storedPreferences[/color]);

[color=#6a9955]    //Dadurch das die Klassen nicht einander kennenlernen können, muss ich einzelne Variablen durchschleifen[/color]
    [color=#569cd6]char[/color] *[color=#9cdcfe]WifiProv_ssid[/color];

    [color=#4ec9b0]WebServer[/color] *[color=#9cdcfe]web_Server[/color];
    [color=#4ec9b0]stored_preference_t[/color] *[color=#9cdcfe]stored_preferences[/color];

[color=#569cd6]private:[/color]
    [color=#569cd6]void[/color] [color=#dcdcaa]handleNotFound[/color]();
    [color=#569cd6]void[/color] [color=#dcdcaa]handle_menu[/color]();
    [color=#569cd6]void[/color] [color=#dcdcaa]handle_css[/color]();
    [color=#569cd6]char[/color] [color=#569cd6]*[/color][color=#dcdcaa]generateHtmlHeader[/color]([color=#569cd6]char[/color] [color=#569cd6]*[/color] [color=#9cdcfe]content[/color],[color=#569cd6]bool[/color] [color=#9cdcfe]add_menu[/color] = [color=#569cd6]true[/color]);
    [color=#569cd6]char[/color] [color=#569cd6]*[/color][color=#dcdcaa]generateHtmlBody[/color]([color=#569cd6]char[/color] [color=#569cd6]*[/color][color=#9cdcfe]input[/color], [color=#569cd6]bool[/color] [color=#9cdcfe]add_menu[/color] = [color=#569cd6]true[/color]);

    
    [color=#4ec9b0]MDNSResponder[/color] [color=#9cdcfe]MDNS[/color];

    [color=#569cd6]const[/color] [color=#569cd6]char[/color] [color=#9cdcfe]html_text[/color][[color=#b5cea8]10[/color]] [color=#569cd6]PROGMEM[/color] = [color=#ce9178]"text/html"[/color];
    [color=#569cd6]const[/color] [color=#569cd6]char[/color] [color=#9cdcfe]html_css[/color][[color=#b5cea8]9[/color]] [color=#569cd6]PROGMEM[/color] = [color=#ce9178]"text/css"[/color];
    [color=#569cd6]const[/color] [color=#569cd6]char[/color] [color=#9cdcfe]text_json[/color][[color=#b5cea8]17[/color]] [color=#569cd6]PROGMEM[/color] = [color=#ce9178]"application/json"[/color];
    [color=#569cd6]const[/color] [color=#569cd6]char[/color] [color=#9cdcfe]json_ok[/color][[color=#b5cea8]16[/color]] [color=#569cd6]PROGMEM[/color] = [color=#ce9178]"{'status':'ok'}"[/color];
    [color=#569cd6]const[/color] [color=#569cd6]char[/color] [color=#9cdcfe]json_error[/color][[color=#b5cea8]19[/color]] [color=#569cd6]PROGMEM[/color] = [color=#ce9178]"{'status':'error'}"[/color];

    


};
[color=#c586c0]#endif[/color]
[/color]

Wenn ich das #include aktiviere kommt es zu besagtem Fehler.

Jemand eine Ahnung woran es liegt?

r1snake:
Ich habe eine Klasse A welche Klasse B included. Klasse A beinhaltet eine Ref variable auf Klasse B.

Du redest in Rätseln. Und mit den ganzen Farbcodes ist das nicht zu lesen.

r1snake:
Jemand eine Ahnung woran es liegt?

Ich habe Dein Posting nur quergelesen. Kann sein, dass ich Dich falsch verstehe.

Du musst der Klasse A quasi „sagen“, dass es eine Klasse B gibt (bzw. geben wird). Das machst Du mit einer „Vorwärts-Deklaration“.

Schreibe in A.h

class B;

Gruß

Gregor

Ich mach mal was Pseudocode aber ich hab als Quote den Code nochmal reinkopiert.

Also:

#include <classB.h>

Class ClassA{
ClassA(ClassB value); -> Im Konstruktur soll eine Instanz auf die ClassA-> RefClassB gesetzt werden
void workWithClassB();
ClassB *RefClassB;

int x = 100;
}


Class ClassB{
ClassB();
void dothis();
void dothat();
}

Das setzen der Referenz klappt ohne Probleme. Ich kann auch ClassA auf die Referenz zugreifen und dann dothis() aufrufen.

Jetzt will ich in dothis() auf Variablen von ClassA zugreifen. Ich könnte im Funktionskopf das als Parameter mitgeben aber in der Realität gibt es mehr als nur eine Variable. Daher möchte ich in Class B ebenfalls eine Referenzvariable anlegen welche auf KlassA zeigt.

Wenn ich nun in der ClassB folgendes hinschreibe "#include <ClassA.h>" dann erhalte ich einen Fehler aus Klasse A das Klasse B nicht mehr gefunden werden kann.

r1snake:
...
#include <classB.h>
...

Du hast meine Antwort nicht richtig umgesetzt. Tu was da steht.

Gruß

Gregor

#ifndef WifiProvider_h
#define WifiProvider_h

#include <WiFi.h>
#include <esp_wifi.h>
#include <NVMProvider.h>
#include <GPSProvider.h>
#include <ESPmDNS.h>
#include "WebServerProvider.h"

#define NMEA_TCP_PORT 1818

#ifdef UPTIME
#include "uptime_formatter.h"
#endif

class WifiProvider
{
public:
WifiProvider();
void init(stored_preference_t *storedPreferences, WebServerProvider *webServerProvider);
void setHostname(const char *hostname);
void wifi_AP();
void wifi_STA();
void nmeaServerStart();
void nmeaServerStop();
void webConfigStart();
void webConfigStop();
stored_preference_t *stored_preferences;
WebServerProvider *webServer_provider;
WiFiServer *nmea_server;
IPAddress MyIP;

char ap_ssid[MAX_AP_NAME_SIZE];
const char ap_password[WIFI_KEY_MAXLEN] = VEDEX_PW;
const uint nmeaServerPort = NMEA_TCP_PORT;
bool wifi_connected = false;

WiFiClient NMEARemoteClient;
private:
};
#endif

#ifndef WEBSERVER_h
#define WEBSERVER_h

#include <WebServer.h>
#include <ESPmDNS.h>
#include <NVMProvider.h>
//#include <WifiProvider.h>

#include <uri/UriBraces.h>
#include <Pagecontent/Header.h>
#include <Pagecontent/Footer.h>
#include <Pagecontent/css.h>
#include <Pagecontent/root_options.h>

#define WEBPORTAL_HEADER_DYN_SIZE 150

class WebServerProvider
{
public:
WebServerProvider();

void wsStart();
void wsStop();
void setStoredPreferences(stored_preference_t *storedPreferences);

//Dadurch das die Klassen nicht einander kennenlernen können, muss ich einzelne Variablen durchschleifen
char *WifiProv_ssid;

WebServer *web_Server;
stored_preference_t *stored_preferences;

private:
void handleNotFound();
void handle_menu();
void handle_css();
char *generateHtmlHeader(char * content,bool add_menu = true);
char *generateHtmlBody(char *input, bool add_menu = true);

MDNSResponder MDNS;

const char html_text[10] PROGMEM = "text/html";
const char html_css[9] PROGMEM = "text/css";
const char text_json[17] PROGMEM = "application/json";
const char json_ok[16] PROGMEM = "{'status':'ok'}";
const char json_error[19] PROGMEM = "{'status':'error'}";

};
#endif

r1snake:
...

Du willst unbedingt gehauen werden, oder?

Gruß

Gregor

Also ich hab jetzt in der WifiProvider.h Datei deine Codezeile hinzugefügt und bekomme einen Error:

error: redefinition of 'class WebServerProvider'

Ich kann dir anscheinend nicht ganz Folgen. Kannst du deinen code in meine Quotes einfügen?

r1snake:
Kannst du deinen code in meine Quotes einfügen?

Nein. Was ich schreibe ist klar und eindeutig.

Gruß

Gregor

Also ich weiß ja nicht ob du richtig lesen kannst aber wenn dein "Ton" etwas härter ist dann ist es meiner auch.

In meiner ersten Quote ist bereits das #include WebServerprovider.h

In meinem zweiten Quote ist ebenfalls das #include WifiProvider.h geschrieben jedoch auskommentiert.

Auskommentiert bekomme ich keinen Fehler und einkommentiert kann die Klasse WifiProvider.h die Klasse WebServerProvider nicht finden kann

r1snake:
Also ich weiß ja nicht ob du richtig lesen kannst aber wenn dein "Ton" etwas härter ist dann ist es meiner auch.

Habe ich irgendwo etwas von #include geschrieben?!

Gruß

Gregor

PS: Na gut. Lies hier (nach dem Codebeispiel).

Okay hab mich wohl doch etwas dumm angestellt.

Klappt jetzt. Werde dann mal schauen ob mein Vorhaben funktioniert.

r1snake:
Okay hab mich wohl doch etwas dumm angestellt.
Klappt jetzt. Werde dann mal schauen ob mein Vorhaben funktioniert.

Danke für die Rückmeldung.

Gruß

Gregor

Kannst du mir noch erklären warum ich das machen muss?

Weil bevor ich Klasse A in Klasse B include kennt Klasse A ja noch Klasse B (Was ein verwirrender Satz :D)

r1snake:
Kannst du mir noch erklären warum ich das machen muss?

Du hast ja quasi ein Henne-Ei-Problem. Das wird dadurch aufgelöst.

Gruß

Gregor

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.