Хобрук: Ваш путь к мастерству в программировании

Не удается заставить производный класс WebDuino работать — ошибки компиляции с «Web_HelloWorld.ino»

Я создал производный класс с именем WebServer_My2KNJ.h из рабочего класса с именем WebServer_My2.h (подробности об этих файлах см. в разделе «Примечания» ниже) и получил следующую ошибку при попытке скомпилировать пример программы: Web_HelloWorld.ino:

Сообщение об ошибке компиляции: (или см. прикрепленный файл 'ErrorMsg.txt'):

Web_HelloWorld.ino: In function 'void setup()':
Web_HelloWorld:57: error: invalid conversion from 'void (*)(WebServer_My2KNJ&, WebServer_My2::ConnectionType, char*, bool)' to 'void (*)(WebServer_My2&, WebServer_My2::ConnectionType, char*, bool)'
Web_HelloWorld:57: error: initializing argument 1 of 'void WebServer_My2::setDefaultCommand(void (*)(WebServer_My2&, WebServer_My2::ConnectionType, char*, bool))'
Web_HelloWorld:61: error: invalid conversion from 'void (*)(WebServer_My2KNJ&, WebServer_My2::ConnectionType, char*, bool)' to 'void (*)(WebServer_My2&, WebServer_My2::ConnectionType, char*, bool)'
Web_HelloWorld:61: error: initializing argument 2 of 'void WebServer_My2::addCommand(const char*, void (*)(WebServer_My2&, WebServer_My2::ConnectionType, char*, bool))'

Строка webserver.setDefaultCommand(&helloCmd); в файле Web_HelloWorld.ino в это время выделена.

Мой производный класс:

/*
  WebServer_My2KNJ.cpp - Extension of the library class 'WebServer_My2'
  Created by: COG008
  Date Created: 2013/10/17
*/

#ifndef WebServer_My2KNJ_h
#define WebServer_My2KNJ_h

#include <..\Webduino_My2\WebServer_My2.h>

class WebServer_My2KNJ: public WebServer_My2
{
public:

// constructor for webserver object
WebServer_My2KNJ(const char *p_urlPrefix = "", int p_port = 80); 
};
WebServer_My2KNJ::WebServer_My2KNJ(const char *p_urlPrefix, int p_port) : 
WebServer_My2::WebServer_My2(p_urlPrefix, p_port)
{
;
}

#endif

Примечание.

  1. Я новичок в C++, так что терпите меня.
  2. Все используемые файлы, кроме «WebServer_My2KNJ.h», в основном такие же, как и в «https://github.com/sirleech/Webduino. '.
  3. «Web_HelloWorld.ino» компилируется и работает нормально, если я использую «WebServer_My2.h» вместо «WebServer_My2KNJ.h».
  4. В родительском классе «WebServer_My2.h» все, что я сделал, это модифицировал «WebServer.h», изменив «private:» на «protected:» и имя класса.
  5. Причина, по которой я иду на эту проблему, заключается в том, что я хочу позже добавить больше функциональности в этот класс. Следовательно, чтобы все было чище и проще, лучше всего иметь свой код в производном классе.

  • Вы вообще меняли параметры helloCmd()? 18.10.2013
  • Нет, я не вносил никаких изменений в функцию helloCmd(). Как я уже говорил ранее, если я #include «WebServer_My2.h» вместо «WebServer_My2KNJ.h», приложение Arduino «Web_HelloWorld.ino» компилируется и работает нормально. Немодифицированную версию этого приложения 'Web_HelloWorld.ino' можно просмотреть по ссылке, указанной выше ('github.com /sirleech/Webduino'). 18.10.2013
  • Проблема в том, что helloCmd, которое передается setDefaultCommand(), не совсем соответствует ожидаемому. Если вы не изменяли его, то должно быть что-то еще, влияющее на его параметры, например. typedef где-то. Откуда взялся WebServer_My2.h? Это точно так же, как WebServer.h? 18.10.2013
  • Он взят из основного файла «Webserver.h», найденного в библиотеке Webduino (см. ссылку на github, приведенную выше). Все, что я сделал, как я сказал выше, это изменил имя файла и класса на «WebServer_My2.h» и сделал частные свойства «защищенными». Примечание. Приложение компилируется и работает нормально, если я вместо этого #включаю этот класс: 'WebServer_My2.h'. 18.10.2013

Ответы:


1

Короткий ответ:

Измените helloCmd() на WebServer_My2& вместо WebServer_My2KNJ&.

Длинный ответ:

Похоже, проблема связана с typedef указателя функции Command в вашем файле WebServer_My2.h. Предположительно он объявлен следующим образом (строка ~169):

typedef void Command(WebServer_My2 &server, ConnectionType type,
                     char *url_tail, bool tail_complete);

Это означает, что это указатель на функцию, которая принимает ссылку на объект WebServer_My2 в качестве своего первого параметра (за которым следуют некоторые другие). Есть некоторые методы, такие как setDefaultCommand(), которые принимают указатели функций именно этого типа. С++ здесь строг. Вы не можете заменить другой указатель функции, который принимает ссылочные параметры производного типа.

Я знаю, вы сказали, что не изменяли helloCmd, но, основываясь на сообщении об ошибке, я должен предположить, что вы действительно изменили список параметров на это:

void helloCmd(WebServer_My2KNJ &server, WebServer_My2::ConnectionType type, char *, bool)

Поэтому проблема возникает, когда код пытается выполнить следующие строки:

webserver.setDefaultCommand(&helloCmd);
webserver.addCommand("index.html", &helloCmd);

Методы setDefaultCommand() и addCommand() ожидают указатель на функцию, который принимает ссылку WebServer_My2 в качестве первого параметра. Однако helloCmd() на самом деле принимает ссылку WebServer_My2KNJ. Это не сработает, потому что типы разные (даже если один является производным от другого).

Быстрое решение — изменить helloCmd(), как я предложил в коротком ответе выше. Таким образом, он должен, по крайней мере, иметь возможность скомпилировать и запустить пример. Если вы хотите использовать расширенный функционал, который вы добавили в свой подкласс, то вы можете сделать это в функции:

WebServer_My2KNJ * myServer = dynamic_cast<WebServer_My2KNJ*>(&server);
if (myServer) {
    // myServer is safe to use here
}

Затем вы можете использовать указатель myServer для доступа ко всем добавленным вами функциям веб-сервера. Просто помните, что это указатель, поэтому вам нужно использовать оператор -> вместо оператора . для доступа к членам.

dynamic_cast преобразует иерархию наследования вниз, если это возможно. Он возвращает нулевой указатель (0), если преобразование не работает, поэтому необходим блок if ().

18.10.2013
  • Привет, Питер: Твой жесткий; Top Notch и т. д. Я последовал вашему короткому совету; создал WebServer_My2.cpp для использования с сокращенным «WebServer_My2.h», и он заработал, как только я включил класс «WebServer_My2.h» в приложение «Web_HelloWorld.ino». Например, компилятор выдавал ошибку неопределенной ссылки на `WebServer_My2::processConnection(char*, int*)' и т. д., если он не включал дополнительное включение. 21.10.2013
  • Новые материалы

    Как ИИ меняет сельское хозяйство
    Прочтите Статью Кэтлин Уолч в Forbes о том, как ИИ меняет сельское хозяйство . Сельское хозяйство и земледелие - одна из древнейших и важнейших профессий в мире. Человечество прошло долгий..

    Slack: проектирование современных интерфейсов человека и ИИ
    Когда Стюарт Баттерфилд выделил Slack из быстро исчезающей онлайн-игры Tiny Speck, его перспективы были в лучшем случае неопределенными. Существовал очевидный спрос на средства связи на рабочем..

    HTTP1.1 против HTTP2
    Http расшифровывается как HyperText Transfer Protocol, это в основном метод, который компьютеры и серверы используют для запроса и отправки информации. HTTP1.1 - это более старая версия Http, а..

    Радость вырезания
    Радость фрагментов По какой-то причине, когда я начал программировать в колледже, я активно сопротивлялся целому ряду земных благ, которые сделали бы мою жизнь чуточку удобнее. Я в основном..

    Создайте стройный слайдер с нуля без каких-либо внешних инструментов
    Слишком долго я полагался на сторонние плагины и инструменты для простых слайдеров. Пока в один прекрасный день в моей крошечной голове не загорелась лампочка, которую я могу сделать..

    Буферы протоколов, часть 01: соглашения об именах и файловая организация
    Если вам нравится читать статьи на Medium и вы заинтересованы в том, чтобы стать участником, я буду рад поделиться с вами своей реферальной ссылкой!

    Наши партнеры
    Globex SCI — уникальная система, которая хранит и позволяет использовать большие базы данных, опубликованные в блокчейне. Используя алгоритмы глубокого обучения и ИИ, мы можем прогнозировать..