Как передать нестатический член класса для обратного вызова на платформах avr?
Я использую библиотеку PubSubClient в своей собственной библиотеке Arduino. У меня возникли проблемы с попыткой назначить член класса в качестве функции обратного вызова setCallback клиентской библиотеки.
MyClass.cpp :
#include <PubSubClient.h>
#include <Wifi.h>
#include "Arduino.h"
#include "MyClass.h"
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
void MyClass::connect(String host, int port) {
mqttClient.begin(host, port, "/");
mqttClient.setCallback(incomingEventHandler);
}
void MyClass::loop() {
mqttClient.loop();
}
void MyClass::incomingEventHandler(char* type, byte *payload, unsigned int length) {
// делать что-то с входящими данными
// необходимо получить доступ к другим функциям-членам и переменным класса
}
MyClass.h:
#ifndef MyClass_h
#define MyClass_h
#include <PubSubClient.h>
#include <Wifi.h>
#include "Arduino.h"
class MyClass {
public:
void connect(String host, int port);
void loop();
void incomingEventHandler(WStype_t type, uint8_t *payload, size_t length);
};
#endif
Ошибка, которую я вижу, заключается в следующем:
sketch/MyClass.cpp: In member function 'void MyClass::connect(String, int)': MyClass.cpp:14:47: error: no matching function for call to 'PubSubClient::setCallback()'
mqttClient.setCallback(incomingEventHandler);
Если я перемещаю функцию incomingEventHandler за пределы определения класса, она работает должным образом, однако тогда я не могу вызывать другие члены класса или получать доступ к свойствам класса в той же области.
В arduino c ++ как я могу передать нестатические свойства члена класса в качестве обратного вызова? Есть ли лучший способ подойти к этому?
P.S. Этот код предназначен только для того, чтобы показать намерение. Возможно, это тоже не будет компиляцией. Был похожий вопрос, подобный этому: Как передать нестатического члена класса в обратный вызов?
но это для esp-8266, а это для платы на базе avrmega4809.
@Hemant Bhargava, 👍1
Обсуждение1 ответ
Ты не можешь. На платформе AVR PubSubClient::setCallback()
ожидает
необработанный указатель на функцию в качестве обратного вызова, и это то, что вы должны
предоставить. Статический метод эквивалентен необработанной функции, нестатический
метод - нет, и ни один из них не является функтором или std::function
.
Если вам нужно больше одного объекта MyClass, одним из решений может быть
изменение библиотеки pubsubclient, чтобы она сохраняла указатель на
ваш
экземпляр MyClass и передавала этот указатель вашему обратному вызову. Если вам
никогда не приходилось, чтобы экземпляры
MyClass
подписывались на один и тот же раздел,
лучшим решением может быть статическое сохранение сопоставления между разделами
и экземплярами MyClass и, в рамках обратного вызова, использование этой сопоставления для поиска
соответствующего экземпляра.
Технически вы можете это сделать, но не без изменения библиотеки. Самым простым способом было бы чисто определить класс виртуального интерфейса и наследовать от него и переопределить метод обратного вызова. Другим способом было бы https://www.tutorialspoint.com/function-pointer-to-member-function-in-cplusplus (изменения, аналогичные первому способу), @KIIV
- программирование ардуино на чистом с
- Используйте Arduino Uno для программирования встроенной Atmega328 на C
- Как создать и загрузить программу на C++ без библиотеки Arduino или IDE?
- Конечный автомат C++ / Wpmf-конверсия
- Как использовать SPI на Arduino?
- Тайм-аут связи Arduino Mega с ошибкой программатора
- Подключение HX711 к трехпроводному датчику нагрузки
- Правильное использование * и & при передаче объектов в методах.
Лично я обычно пишу небольшую оболочку, которая вызывает функцию для глобального объекта. Либо как обычная функция, либо как статическая функция, если мне когда-либо понадобится только один экземпляр. Грубо, но эффективно., @Majenko