2017-11-20 19 views
2

私はParticle projectに取り組んでおり、JSから来ているので、私はC++のコールバックに挑戦しています。私は、再利用可能なクラスに私のFirebaseコードをリファクタリングしようとしています。このために、私は、コールバックが必要です。ArduinoプロジェクトのC++でのコールバック

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を静的なものはすべて動作するようですが、自然に私はコールバックにアクセスするのに問題があります。

invalid use of member 'Firebase::_readCallback' in static member function

それは静的ではない場合は、私はこの行のために得る:

Particle.subscribe("hook-response/test3rdata", getDataHandler, MY_DEVICES); 

次のエラー:私はそれをバインドしようとすると

invalid use of non-static member function

here助言として:

Particle.subscribe("hook-response/test3rdata", std::bind(&Firebase::getDataHandler,this), MY_DEVICES); 

I Particle.subscribeがバインドされたメソッドを期待しないのでミスタイプを取得します。

no matching function for call to 'CloudClass::subscribe(const char [25], std::_Bind_helper::type, Spark_Subscription_Scope_TypeDef)'

周囲に道がありますか?

+0

は限り私のC++の理解が私に語ったように、いくつかの内部ファームウェアEventHandlerクラスです:https://github.com/ spark/firmware/blob/e854596ef86286a789d19018a136f41cc2fe6f8b/system/src/system_cloud.cpp void eventHandler(system_event_tイベント、intデータ、void *){ – Guy

答えて

1

std::bindは、void()であり、void(char const*, char const*)ではなく、署名に準拠した関数オブジェクトを返すため、このエラーが発生しています。なぜなら、それらの引数のプレースホルダを指定しなかったからです。だから、簡単な修正は次のようになります。

std::bind(&Firebase::getDataHandler, this, std::placeholders::_1, std::placeholders::_2) 

今バインドヘルパーは、それがバインドされたメンバ関数に転送する2つのパラメータを期待しています。


すべてのことを言って、ラムダで十分であれば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); 
+0

驚くばかり!期待どおりに動作します。 – Guy

関連する問題