Я работаю над Частичный проект и исходящих от JS, поэтому мне бросают вызов обратные вызовы в C ++. Я пытаюсь преобразовать мой код Firebase в повторно используемый класс, и для этого мне нужны обратные вызовы:
void setup() {
firebase = new Firebase;
Serial.begin(9600);
firebase->subscribe();
firebase->setCallback(readCallback);
}
void readCallback(JsonObject& root)
{
r = root["r"];
g = root["g"];
b = root["b"];
Serial.printlnf("Yes! r=%d g=%d b=%d d=%d", r, g, b);
}
Firebase.h:
#ifndef Firebase_h
#define Firebase_h
#include <SparkJson.h>
class Firebase {
public:
Firebase();
void
subscribe(),
setCallback(void (*readCallback)(JsonObject& root));private:
static void getDataHandler(const char *topic, const char *data);
void (*_readCallback)(JsonObject& root);
};
#endif
Firebase.m:
#include "Particle.h"// This #include statement was automatically added by the Particle IDE.
#include <SparkJson.h>
#include "ArduinoJson.h"#include "Firebase.h"
Firebase::Firebase(void) {
Serial.printlnf("Firebase instance created");
}
void Firebase::getDataHandler(const char *topic, const char *data) {
Serial.printlnf("getDataHandler invoked");
StaticJsonBuffer<256> jsonBuffer;
char *mutableCopy = strdup(data);
JsonObject& root = jsonBuffer.parseObject(mutableCopy);
free(mutableCopy);
Serial.printlnf("data received: %s", data);
// _readCallback(root);
}
void Firebase::subscribe() {
Serial.printlnf("Firebase subscribe");
Particle.subscribe("hook-response/test3rdata", getDataHandler, MY_DEVICES);
}
void Firebase::setCallback(void (*readCallback)(JsonObject& root))
{
Serial.printlnf("set callback");
_readCallback = readCallback;
}
Когда getDataHandler статичен, кажется, что все работает, но, естественно, у меня возникают проблемы с доступом к обратному вызову, и я получаю:
недопустимое использование элемента ‘Firebase :: _ readCallback’ в статическом члене
функция
Когда это не статично, я получаю для этой строки:
Particle.subscribe("hook-response/test3rdata", getDataHandler, MY_DEVICES);
следующая ошибка:
недопустимое использование нестатической функции-члена
Когда я пытаюсь связать это, как советовали Вот:
Particle.subscribe("hook-response/test3rdata", std::bind(&Firebase::getDataHandler,this), MY_DEVICES);
Я получаю опечатку, так как Particle.subscribe не ожидает связанного метода:
нет подходящей функции для вызова CloudClass :: подписка (const char
[25], std :: _ Bind_helper :: type, Spark_Subscription_Scope_TypeDef) ‘
Есть ли способ обойти это?
Вы получаете эту ошибку, потому что std::bind
возвращает объект функции, который придерживается подписи void()
и не void(char const*, char const*)
, Причина в том, что вы не указали никаких заполнителей для этих аргументов. Таким образом, быстрое решение будет:
std::bind(&Firebase::getDataHandler, this, std::placeholders::_1, std::placeholders::_2)
Теперь помощник bind ожидает два параметра, которые он будет перенаправлять в связанную функцию-член.
Сказав все это, нет смысла использовать std::bind
если лямбда будет достаточно. Лямбды на самом деле превосходят во многих отношениях. В C ++ 14 практически нет причин использовать std::bind
совсем. И даже в C ++ 11 ваш вариант использования может быть обработан простой лямбда-выражением:
Particle.subscribe("hook-response/test3rdata", [this](char const* a, char const* b) { getDataHandler(a, b); }, MY_DEVICES);
Других решений пока нет …