我找到了this问题,但答案似乎不符合我的要求。 答案建议使用
static
函数,而不是我需要访问类成员。
我的(不工作的)理想代码是:
在 myclass.h 中:
private:
int foo = 0;
hw_timer_t *_timer1s;
void Setup();
在 myclass.cpp 中:
void MyClass::Setup()
{
_timer1s = timerBegin(0, 80, true);
timerAttachInterrupt(_timer1s, [this]()
{
foo++;
}, true);
}
当然我得到了已知的转换错误:
不存在从“lambda ->void”到“void (*)()”的合适转换函数
我理解链接问题的解释,但我不明白如何更改建议的代码以捕获/访问类成员(即
foo
)。使用 static
函数不允许我这样做。
这里正确的语法是什么?
根据要求,我添加了整个班级代码:
我的班级.h
#ifndef MYCLASS_H
#define MYCLASS_H
#include <Arduino.h>
#include <RTClib.h>
class MyClass
{
public:
MyClass();
private:
int foo = 0;
hw_timer_t *_timer1s;
void Setup();
};
#endif // MYCLASS_H
myclass.cpp:
#include "myclass.h"
MyClass::MyClass()
{
Setup();
}
void MyClass::Setup()
{
_timer1s = timerBegin(0, 80, true);
timerAttachInterrupt(_timer1s, [this]()
{
foo++;
}, true);
timerAlarmWrite(_timer1s, 1000000, true);
timerAlarmEnable(_timer1s);
}
这里编译输出错误:
src/myclass.cpp: In member function 'void MyClass::Setup()':
src/myclass.cpp:40:12: error: cannot convert 'MyClass::Setup()::<lambda(void*)>' to 'void (*)()'
}, true);
In file included from /home/mark/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal.h:92,
from /home/mark/.platformio/packages/framework-arduinoespressif32/cores/esp32/Arduino.h:36,
from include/myclass.h:4,
from src/myclass.cpp:1:
/home/mark/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-timer.h:40:53: note: initializing argument 2 of 'void timerAttachInterrupt(hw_timer_t*, void (*)(), bool)'
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge);
Visual Studio Code 的内联助手报告:
不存在从“lambda ->void”到“void (*)()”的合适转换函数
捕获 lambda 与您需要提供给
void(*)()
的 timerAttachInterrupt
不匹配。解决方案是使用 timerAttachInterruptArg
代替并提供 this
作为参数:
void MyClass::Setup()
{
_timer1s = timerBegin(0, 80, true);
timerAttachInterruptArg(_timer1s, [](void* instance)
{
// cast `instance` back to a `MyClass*`:
auto This = static_cast<MyClass*>(instance);
This->foo++;
}, this);
// ^^^^ this becomes `void* instance` in the lambda
//...
}
当然,如果
foo
是私有的,这将不起作用。您可以调用 static
成员函数而不是 lambda 来解决这个问题。