回调定义不兼容

Callback definition is incompatible

我使用具有这些定义的 a library

typedef void (*CallbackFunction) (ESPRotary&);
void ESPRotary::setChangedHandler(CallbackFunction f) { ... }

当我尝试使用 setChangedHandler 函数时,出现回调定义错误的问题。

#pragma once

#include "ESPRotary.h"

class MyUsermod : public Usermod
{
private:
  ESPRotary r = ESPRotary(13, 12);

public:
  void rotate(ESPRotary &r)
  {
    Serial.println(r.getPosition());
  }

  void setup()
  {
    // argument of type "void (MyUsermod::*)(ESPRotary &r)" is incompatible 
    // with parameter of type "ESPRotary::CallbackFunction"C/C++(167)
    r.setChangedHandler(rotate); 
  }
};

我做错了什么?

void rotate(ESPRotary &r)

这不是函数。这是一个(非静态)class 方法。这被声明为 class MyUsermod 的成员,与声明名为 rotate() 的函数完全不同的是一些随机选择的 .cpp 文件,没有进一步的上下文。

Class 方法需要调用 classes 的实例。 rotate的类型是

void (MyUsermod::*) (ESPRotary&)

而不是

void (*) (ESPRotary&)

这回答了编译错误的原因,以及类型不匹配。

至于如何解决这个问题,对于这个问题的每个实例都没有统一的解决方案。这完全取决于这些对象在程序的其余部分中的使用方式。最灵活的解决方案是将 CallbackFunction 更改为正确的类型,然后在调用回调的代码中决定将调用哪个 class 实例的方法。

在class:

内部定义回调函数需要静态定义
class MyUsermod : public Usermod
{
private:
  ESPRotary r = ESPRotary(13, 12);

public:
  /* Callback function "static" defined */
  static void rotate(ESPRotary &r)
  {
    Serial.println(r.getPosition());
  }

  void setup()
  {
    r.setChangedHandler(rotate); 
  }
};
参考资料
  • Why callback functions needs to be static when declared in class?