• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Не верная проверка на null

Const

Member
Привет. Использую библиотеку AsyncWiFiManager для подключения к wifi в которой есть возможность устанавливать кастомные параметры на страницу настроек подключения. Ниже код который я набросал для генерации ошибки.
C++:
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncWebServer.h>
#include <ESP8266HTTPClient.h>
#include <DNSServer.h>
#include <ESPAsyncWiFiManager.h>
#include "LittleFS.h"

AsyncWebServer server(80);
DNSServer dns;

void setup() {
    Serial.begin(115200);
    LittleFS.begin();
    AsyncWiFiManager wifiManager(&server, &dns);
    wifiManager.setDebugOutput(true);

    AsyncWiFiManagerParameter param_mqtt_title("<h3>Title</h3>");
    AsyncWiFiManagerParameter param_mqtt_checkbox("mqtt", "", "1", 1, " type=\"checkbox\"");
    AsyncWiFiManagerParameter param_mqtt_checkbox_label("<label for=\"mqtt\">Using MQTT</label>");
    AsyncWiFiManagerParameter div("<div></div>");
    AsyncWiFiManagerParameter param_mqtt_ip_label("<label for=\"mqtt_ip\">Mqtt ip:</label>");
    AsyncWiFiManagerParameter param_mqtt_ip("mqtt_ip", "0.0.0.0", "", 16, " type=\"text\" disabled");
    AsyncWiFiManagerParameter param_mqtt_port_label("<label for=\"mqtt_port\">Mqtt port:</label>");
    AsyncWiFiManagerParameter param_mqtt_port("mqtt_port", "1883", "1883", 5, " type=\"text\" disabled");
    AsyncWiFiManagerParameter param_mqtt_user_label("<label for=\"mqtt_user\">Mqtt user:</label>");
    AsyncWiFiManagerParameter param_mqtt_user("mqtt_user", "User", "", 16, " type=\"text\" disabled");
    AsyncWiFiManagerParameter param_mqtt_pass_label("<label for=\"mqtt_pass\">Mqtt password:</label>");
    AsyncWiFiManagerParameter param_mqtt_pass("mqtt_pass", "", "", 16, " type=\"text\" disabled");
    AsyncWiFiManagerParameter param_mqtt_script("<script>function b(d){mqtt_ip.disabled = mqtt_port.disabled = mqtt_user.disabled = mqtt_pass.disabled = d}mqtt.addEventListener('change', (event) => b(!mqtt.checked));</script>");

    wifiManager.addParameter(&param_mqtt_title);
    wifiManager.addParameter(&param_mqtt_checkbox);
    wifiManager.addParameter(&param_mqtt_checkbox_label);  
    wifiManager.addParameter(&div);
    wifiManager.addParameter(&param_mqtt_ip_label);
    wifiManager.addParameter(&param_mqtt_ip);
    wifiManager.addParameter(&param_mqtt_port_label);
    wifiManager.addParameter(&param_mqtt_port);
    wifiManager.addParameter(&param_mqtt_user_label);
    wifiManager.addParameter(&param_mqtt_user);
    wifiManager.addParameter(&param_mqtt_pass_label);
    wifiManager.addParameter(&param_mqtt_pass);
    wifiManager.addParameter(&param_mqtt_script);
   
    wifiManager.autoConnect(("Module-"+String(ESP.getChipId())).c_str());
}

void loop() {
}
Самый первый параметр 'param_mqtt_title' должен просто выводить HTML, но по каким то причинам текст который передан в конструктор вставляется в тег input. Я порылся в коде библиотеки и понял что условие
C++:
_params[i]->getID() != NULL
Возвращает true из за чего дальнейшее выполнение идет не по тому сценарию. В конструкторе
C++:
AsyncWiFiManagerParameter::AsyncWiFiManagerParameter(const char *custom)
{
  _id = NULL;
  _placeholder = NULL;
  _length = 0;
  _value = NULL;

  _customHTML = custom;
}
В поле _id устанавливается null и далее нигде не меняется.
 

Const

Member
Код:
Serial. println(_params[i]->getID());
ничего не выводит как при значении null.
C++:
_params[i]->getID() != NULL
Почему срабатывает это условие??? У меня кончились идеи как решить этот вопрос. Библиотека тут.
 

CodeNameHawk

Moderator
Команда форума
Самый первый параметр 'param_mqtt_title' должен просто выводить HTML
Где это видно?
Я вижу такое
Код:
class AsyncWiFiManagerParameter
{
public:
  AsyncWiFiManagerParameter(const char *custom);
  AsyncWiFiManagerParameter(const char *id,
                            const char *placeholder,
                            const char *defaultValue,
                            unsigned int length);
  AsyncWiFiManagerParameter(const char *id,
                            const char *placeholder,
                            const char *defaultValue,
                            unsigned int length,
                            const char *custom);
 

Const

Member
Где это видно?
Я вижу такое
Код:
class AsyncWiFiManagerParameter
{
public:
  AsyncWiFiManagerParameter(const char *custom);
  AsyncWiFiManagerParameter(const char *id,
                            const char *placeholder,
                            const char *defaultValue,
                            unsigned int length);
  AsyncWiFiManagerParameter(const char *id,
                            const char *placeholder,
                            const char *defaultValue,
                            unsigned int length,
                            const char *custom);
Первый параметр в моем примере использует один из конструкторов кот который вы показали. А именно - AsyncWiFiManagerParameter(const char *custom);
Перебор и формирование HTML из параметров начинается в цикле в стоке 959
C++:
for (unsigned int i = 0; i < _paramsCount; i++)
  {
    if (_params[i] == NULL)
    {
      break;
    }

    String pitem = FPSTR(HTTP_FORM_PARAM);
    if (_params[i]->getID() != NULL)
    {
      pitem.replace("{i}", _params[i]->getID());
      pitem.replace("{n}", _params[i]->getID());
      pitem.replace("{p}", _params[i]->getPlaceholder());
      snprintf(parLength, 2, "%d", _params[i]->getValueLength());
      pitem.replace("{l}", parLength);
      pitem.replace("{v}", _params[i]->getValue());
      pitem.replace("{c}", _params[i]->getCustomHTML());
    }
    else
    {
      pitem = _params[i]->getCustomHTML();
    }

    page += pitem;
  }
HTML должен формироваться в ветке else pitem = _params->getCustomHTML(); Но выполнение кода происходит в ветке if так как условие _params->getID() != NULL возвращает true и я не понимаю почему. Поле _id в конструкторе инициализируется в null.
 
Сверху Снизу