Bräuchte Hilfe mit meiner ersten Library Error: invalid use of non-static data .

Hallo zusammen,

Bin gerade dabei mir meine erste Library zu schreiben und stecke leider fürchterlich :frowning:

Es geht um eine OTA Update Library für den ESP32 Chip die ich nicht jedes mal neu direkt in den Code schreiben will. (Stellt eine Website zu Verfügung um die Bin Datei hochzuladen)

Dabei sollen drei const char* Variablen an die Library übergeben und dort verarbeitet werden:

const char* ota_host = "host";
const char* ota_user = "admin";
const char* ota_password = "admin";

Definiere ich die Variablen direkt in der cpp läuft die Library problemlos !

Wenn ich sie über den Constructor übergebe bekomme ich bei ota_user und ota_password folgende Fehlermeldung:

error: invalid use of non-static data member ‘Webota::_user’
error: invalid use of non-static data member ‘Webota::_password’

Habe jetzt schon einige stunden auf Google verbracht und den Code x mal umgeschrieben komme leider einfach auf keine Lösung :frowning:

Hier der ganze Code (habe für die bessere lesbarkeit das wlanconnect etc entfernt):

.ino:

#include <Arduino.h>
#include <WiFi.h>
#include <Webota.h>

const char* ota_host = "host";
const char* ota_user = "admin";
const char* ota_password = "admin";
Webota ota(ota_host, ota_user, ota_password);


void setup() {
ota.setup();
}

void loop() {
ota.loop();
}

Webota.h:

#ifndef webota
#define webota

#if (ARDUINO >=100)
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

class Webota  {
  public:
    // Constructor 
    Webota(const char* ota_host, const char* ota_user, const char* ota_password);

    // Methods
    void setup();
    void loop();

  private:
    const char* _host;
    const char* _user;
    const char* _password;
};
#endif

Webota.cpp:

#include <Webota.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <Update.h>


Webota::Webota(const char* ota_host, const char* ota_user, const char* ota_password) {
  _host = ota_host;
  _user = ota_user;
  _password = ota_password;
}

// So geht es !
//const char* _user = "admin";
//const char* _password = "passw";

WebServer server(80);

//Server Index
const char* serverIndex = 
"<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
   "<input type='file' name='update'>"
        "<input type='submit' value='Update'>"
    "</form>"
 "<div id='prg'>progress: 0%</div>"
 "<script>"
  "$('form').submit(function(e){"
  "e.preventDefault();"
  "var form = $('#upload_form')[0];"
  "var data = new FormData(form);"
  " $.ajax({"
  "url: '/update',"
  "type: 'POST',"
  "data: data,"
  "contentType: false,"
  "processData:false,"
  "xhr: function() {"
  "var xhr = new window.XMLHttpRequest();"
  "xhr.upload.addEventListener('progress', function(evt) {"
  "if (evt.lengthComputable) {"
  "var per = evt.loaded / evt.total;"
  "$('#prg').html('progress: ' + Math.round(per*100) + '%');"
  "}"
  "}, false);"
  "return xhr;"
  "},"
  "success:function(d, s) {"
  "console.log('success!')" 
 "},"
 "error: function (a, b, c) {"
 "}"
 "});"
 "});"
 "</script>";



// this is our 'begin' function
void Webota::setup() {
  /*use mdns for host name resolution*/
  if (!MDNS.begin(_host)) { 
    Serial.println("Error setting up MDNS responder!");
    while (1) {
      delay(1000);
    }
  }
  Serial.println("mDNS responder started");
  /*return index page which is stored in serverIndex */
   server.on("/", [](){
    if(!server.authenticate(_user, _password))                   // Hier liegt der Fehler ...
      return server.requestAuthentication();
    server.send(200, "text/html", serverIndex);
  });

  server.on("/serverIndex", HTTP_GET, []() {
    server.sendHeader("Connection", "close");
    server.send(200, "text/html", serverIndex);
  });
  /*handling uploading firmware file */
  server.on("/update", HTTP_POST, []() {
    server.sendHeader("Connection", "close");
    server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
    ESP.restart();
  }, []() {
    HTTPUpload& upload = server.upload();
    if (upload.status == UPLOAD_FILE_START) {
      Serial.printf("Update: %s\n", upload.filename.c_str());
      if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size
        Update.printError(Serial);
      }
    } else if (upload.status == UPLOAD_FILE_WRITE) {
      /* flashing firmware to ESP*/
      if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
        Update.printError(Serial);
      }
    } else if (upload.status == UPLOAD_FILE_END) {
      if (Update.end(true)) { //true to set the size to the current progress
        Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
      } else {
        Update.printError(Serial);
      }
    }
  });
  server.begin();

}

void Webota::loop()
{
  server.handleClient();
  delay(1);
}

Ich hoffe ihr könnt mir weiterhelfen.

Herzlichen Dank !

lg
Patrick

private:
    const char* _host;
    const char* _user;
    const char* _password;

Du kannst einer als 'const' deklarierten Variable keinen Wert zuweisen, das geht nur direkt bei der Initiierung. Statt der Zuweisungen musst Du beim Konstruktor eine Initialisierungsliste verwenden.

Webota::Webota(const char* ota_host, const char* ota_user, const char* ota_password)
           :  _host(ota_host), _use(ota_user),  _password(ota_password)
{
}

Hallo Franz-Peter,

Herzlichen Dank für deine Hilfe !

Das const car* variablen nicht veränderbar sind dürfte ich verdrängt haben und auf die Lösung mit der Initialisierungsliste wäre ich vermutlich nie gekommen.

Habe jetzt die Initialisierungsliste in den Code eingefügt diese dürfte auch funktionieren.

Der Fehler besteht aber leider weiterhin hat sich aber um einen Punkt erweitert ...
Jetzt ist ein lambda Fehler dazu gekommen:

lib\webota\Webota.cpp:78:36: error: 'this' was not captured for this lambda function
if(!server.authenticate(_user, _password))
^
lib\webota\Webota.cpp:78:36: error: invalid use of non-static data member 'Webota::_password'
In file included from lib\webota\Webota.cpp:1:0:
lib/webota/Webota.h:25:17: note: declared here
const char* _password;

Die gleichen Meldungen erscheinen auch für die _user Variable.

Was mir komisch vorkommt ist das die _host Variable die absolut gleich wie _user und _password implementiert ist ohne Probleme funktioniert (übernommen wird).

Für mich sieht es so aus als würde sich das server.authenticate (Klasse vom originalen WebServer.h) an der Implementierung / Übergabe der Variablen stören.

Definiert man die beiden Variablen _user / _passwort mit const char* direkt in der Webota.cpp funktioniert die Library ohne Probleme :slight_smile:

Aber da ich nicht jedes mal die beiden direkt in der Library ändern will ist das leider etwas suboptimal :frowning:

DANKE
lg
Patrick

Hallo Patrick,
ich kenne mich mit lambda-Ausdrücken nicht wirklich aus. Soweit ich weis, kann man da aber nicht so ohne weiteres auf Variable außerhalb des Lambda-Ausdrucks zugreifen, sondern muß dies explizit angeben ( in der Erfassungsliste ). Vielleicht ist es in deinem Fall besser, dies als normale Funktion zu schreiben, und nur den Funktionspointer zu übergeben.
Ansonsten versuche es mal mit:

server.on("/", [_user, _password](){
    if(!server.authenticate(_user, _password))                   // Hier liegt der Fehler ...