【问题标题】:C++ callback to class function类函数的 C++ 回调
【发布时间】:2017-06-04 14:01:08
【问题描述】:

我正在使用 Arduino IDE 和 things network arduino 库来创建 LoRa mote。

我创建了一个类来处理所有与 LoRa 相关的功能。在此类中,如果我收到下行链路消息,我需要处理回调。 ttn 库有一个 onMessage 函数,我想在我的 init 函数中设置它并解析另一个函数,它是一个类成员,称为 message。 我收到错误“无效使用非静态成员函数”。

// File: LoRa.cpp
#include "Arduino.h"
#include "LoRa.h"
#include <TheThingsNetwork.h>

TheThingsNetwork ttn(loraSerial,debugSerial,freqPlan);

LoRa::LoRa(){ 
}

void LoRa::init(){
  // Set the callback
  ttn.onMessage(this->message);
}

// Other functions

void LoRa::message(const uint8_t *payload, size_t size, port_t port)
{
  // Stuff to do when reciving a downlink
}

还有头文件

// File: LoRa.h
#ifndef LoRa_h
#define LoRa_h

#include "Arduino.h"
#include <TheThingsNetwork.h>

// Define serial interface for communication with LoRa module
#define loraSerial Serial1
#define debugSerial Serial


// define the frequency plan - EU or US. (TTN_FP_EU868 or TTN_FP_US915)
#define freqPlan TTN_FP_EU868



class LoRa{
  // const vars



  public:
    LoRa();

    void init();

    // other functions

    void message(const uint8_t *payload, size_t size, port_t port);

  private:
    // Private functions
};


#endif

我试过了:

ttn.onMessage(this->message);
ttn.onMessage(LoRa::message);
ttn.onMessage(message);

但是,它们都没有像我预期的那样工作。

【问题讨论】:

  • 一个非静态成员函数需要一个 object 被调用。如果没有对象,就不能使用非静态成员函数。一旦你有一个对象,我建议你看看std::functionstd::bind

标签: c++ class arduino lora


【解决方案1】:

您试图在不使用类成员的情况下调用成员函数(即属于类类型成员的函数)。这意味着,您通常会先实例化您的 LoRa 类的成员,然后将其称为:

LoRa loraMember;    
loraMember.message();

由于您尝试从类本身内部调用该函数,而没有调用 init() 的类成员,因此您必须将函数设为静态:

static void message(const uint8_t *payload, size_t size, port_t port);

然后你可以在任何地方使用 LoRa::message(),只要它是公共的,但是这样调用它会给你另一个编译器错误,因为消息接口要求“const uint8_t *payload, size_t size, port_t 端口”。所以你要做的就是调用消息:

LoRa::message(payloadPointer, sizeVar, portVar);`

当您调用 ttn.onMessage(functionCall) 时,会发生函数调用被求值的情况,然后该函数返回的内容被放入括号中,然后调用 ttn.onMessage。由于您的 LoRa::message 函数不返回任何内容(void),您将在此处收到另一个错误。

我推荐一本关于 C++ 基础的好书来帮助你入门 - book list

祝你好运!

【讨论】:

    【解决方案2】:

    我通过使消息函数成为类外的普通函数来解决问题。不确定这是否是好的做法 - 但它有效。

    // File: LoRa.cpp
    #include "Arduino.h"
    #include "LoRa.h"
    #include <TheThingsNetwork.h>
    
    TheThingsNetwork ttn(loraSerial,debugSerial,freqPlan);
    
    void message(const uint8_t *payload, size_t size, port_t port)
    {
      // Stuff to do when reciving a downlink
    }
    
    LoRa::LoRa(){ 
    }
    
    void LoRa::init(){
      // Set the callback
      ttn.onMessage(message);
    }
    

    【讨论】:

      【解决方案3】:

      您应该将参数传递给massage,如其原型所示:

      void message(const uint8_t *payload, size_t size, port_t port);

      由于massage 返回 void,因此不应将其用作其他函数的参数。

      【讨论】:

        猜你喜欢
        • 2010-11-03
        • 1970-01-01
        • 1970-01-01
        • 2012-03-04
        • 2012-02-07
        • 1970-01-01
        • 1970-01-01
        • 2011-01-18
        • 1970-01-01
        相关资源
        最近更新 更多