Вызов функций между 2 классами

Класс myIOT2 содержит функцию, которую необходимо вызвать из класса IPmonitoring:

bool myIOT2::checkInternet(char *externalSite, byte pings)
{
    return Ping.ping(externalSite, pings);
}

Эта функция необходима как pinger в IPMonitor:

void IPmonitoring::start(cb_func ping)
{

        _ping_cb = ping;
}

и этот cb_func определяется (внутри IPMonitor.h):

typedef bool (*cb_func)(char *externalSite, byte pings);
cb_func _ping_cb;

внутри моего скетча (только соответствующие части) Я терплю неудачу при передаче iot.checkInternet, а использование функционального теста, вызывающего iot.checkInternet, завершается успешно:

myIOT2 iot;
IPmonitoring WiFi_service(ROUTER_IP, "Router");

bool test(char *a, byte b)
{
        bool x = iot.checkInternet(ROUTER_IP);
        return x;
}

void setup()
{
WiFi_service.start(iot.checkInternet); // <---- Trial a)fails
WiFi_service.start(test);              // <-----Trail b)succeeds
}

ошибка заключается в следующем :

home/guy/Documents/git/Arduino/IPmonitor/IPmonitor.ino: In function 'void setup()':
IPmonitor:436:45: error: no matching function for call to 'IPmonitoring::start(<unresolved overloaded function type>)'
         WiFi_service.start(iot.checkInternet);//
                                             ^
/home/guy/Documents/git/Arduino/IPmonitor/IPmonitor.ino:436:45: note: candidate is:
In file included from /home/guy/Documents/git/Arduino/IPmonitor/IPmonitor.ino:2:0:
/home/guy/Documents/git/Arduino/libraries/myIPmonitor/myIPmonitor.h:42:10: note: void IPmonitoring::start(IPmonitoring::cb_func)
     void start(cb_func ping);
          ^
/home/guy/Documents/git/Arduino/libraries/myIPmonitor/myIPmonitor.h:42:10: note:   no known conversion for argument 1 from '<unresolved overloaded function type>' to 'IPmonitoring::cb_func {aka bool (*)(char*, unsigned char)}'
Multiple libraries were found 

Что же сделано не так ? и почему тест проходит успешно ?

, 👍1

Обсуждение

Это ответ на ваш вопрос? Передача указателя на метод, @Juraj

@Juraj Нет :( Я этого не делал, @Guy . D

@Juraj - в основном потому, что прохождение "теста" проходит успешно, @Guy . D

вы прочитали этот ответ до конца?, @Juraj

@Juraj да, но почти с самого начала я не могу понять, @Guy . D

суть проблемы заключается в том, что скомпилированный метод класса содержит объект в качестве первого параметра, поэтому параметры функции обратного вызова не совпадают для cb_func, @Juraj


1 ответ


1

Существует фундаментальное различие между простой функцией и функцией, которая является членом класса. Вы не можете использовать указатель функции для указания на функцию-член класса: просто потому, что эта функция-член также содержит информацию об экземпляре класса, к которому она принадлежит.

Правильный способ обработки C++ - использовать функцию std::, но компилятору Arduino AVR не хватает полного STL (стандартной библиотеки шаблонов), поэтому его нельзя использовать на обычных ардуино. Другие ядра имеют его, так что вы вполне можете использовать его на ESP8266.

Если вы хотите сделать свой код переносимым между системами, которые могут не иметь полного STL, то есть другие трюки, которые вы должны сделать:

  • Используйте функцию обертки (которая, как вы обнаружили, работает), или
  • Создайте полиморфный класс и сохраните указатель на экземпляр, приведенный к родительскому классу - родительский класс определяет функции, которые разрешено вызывать из указателя.
,

Большое вам спасибо за исчерпывающее объяснение. А) это ESP8366. Б) функция-оболочка необходима для какой из моих функций-членов? В) не могли бы вы написать или направить такой пример ? Я должен сказать, что для меня это немного расплывчато., @Guy . D

"Функция-оболочка" - это простая функция, которая вызывает функцию в нужном вам объекте. Ваша функция "тест" из вашего примера. Что - то вроде void test() { MyObject.someFunction ();} - Я использую что-то подобное [здесь](https://github.com/MajenkoLibraries/Mesh/blob/master/nRF24L01/nRF24L01.cpp#L3), @Majenko