处理类内的回调时,必须调用对非静态成员函数的引用
Reference to non-static member function must be called when processing callbacks inside a class
我有PiGPIO库提供的以下API代码。基本上,它允许您在引脚状态更改时设置回调函数。
通常 API 如下所示:
typedef void (*gpio_callback_t)(int, int, uint32_t);
int gpioSetAlertFunc(int, gpio_callback_t)
它可以这样称呼:
void callback_func(int pin, int NewLevel, uint32_t CurrentTicks)
{
// Callback process
}
int main()
{
// Setting up callback function
gpioSetAlertFunc(10, callback_func)
// Do stuff while callback will be called independently
}
现在上面的代码完美运行!
当我尝试将此代码包装在C++类中时,大问题就来了。 该类应如下所示:
class Pin
{
public:
Pin()
{
gpioSetAlertFunc(10, this->internal_gpio_callback) );
}
void internal_callback_func(int pin, int level, uint32_t tick)
{
cout << "New level: " << pin << " " << level;
}
}
问题是不允许引用该函数,因为它不是静态函数。为了使事情更加复杂,我不能只是使回调函数成为静态的。该回调函数将与其他类方法及其内部变量进行大量交互。
您知道解决此问题的方法吗?或者也许是使用指针或其他东西的肮脏黑客?
不间断的C 样式回调将接受void*
参数来传递任意用户定义数据。由于这个没有,所以它是库设计中的一个错误。向库作者提出问题。
要解决此问题,您需要创建一个闭包作为 C 兼容函数。没有办法做到这一点是标准的 C 或 C++。不过,有一些库(不符合标准且不可移植(可以解决此问题。一个这样的库是GNU libffcall,另一个是libffi。两者都允许您创建行为类似于普通 C 函数的闭包。
gpio 库代码没有Pin
类的概念,但是在不知道要调用哪个Pin
对象的情况下,您无法调用成员回调函数。因此,您需要一些(非成员(函数来查找要在函数调用中使用的Pin
对象。
此信息似乎以int pin
参数的形式出现。因此,您需要一个(免费(函数,该函数知道所有Pin
对象以及它们具有的引脚编号,找到正确的对象并调用其回调函数:
class Pin
{
public:
explicit Pin(int pin);
void internal_callback_func(int level, uint32_t tick);
private:
int _pin;
};
// Alternatively a std::array, a std::map or similar.
std::vector<Pin> allPins;
void pinCallback(int pin, int level, uint32_t tick)
{
Pin& pinObject = allPins[pin];
pinObject.internal_callback_func(level, tick);
// The Pin object presumably knows its own number.
}
Pin::Pin(int pin) : _pin(pin)
{
gpioSetAlertFunc(_pin, pinCallback);
}
void Pin::internal_callback_func(int level, uint32_t tick)
{
cout << "New level: " << _pin << " " << level;
}
void mainOrSo()
{
// Create some pins and store them in the vector. Each one registers the callback on construction.
for (int i = 0; i < 16; ++i)
allPins.emplace_back(i);
}
相关文章:
- 在 nullptr 上调用无状态类的非静态成员函数是否合法?
- 非静态成员失败的线程调用函数
- 处理类内的回调时,必须调用对非静态成员函数的引用
- LNK2019 在文件中调用静态成员的方法时出错.cpp
- 为什么我不能像这样在静态成员函数中调用静态成员变量?
- 当我在C++中调用 struce 的只读静态成员时,线程是否安全
- 简化静态成员函数调用的方法
- 通过指针调用静态成员函数
- Visual 2015 C++编译器:使用对象调用静态成员不会导致编译器错误
- 在不存在的对象上调用静态成员函数
- 在静态成员变量初始值设定项中,为什么调用静态成员函数(而不是全局函数)
- 为什么在包含类的构造函数之前调用静态成员的构造函数
- 编译递归模板以调用静态成员函数时类型不完整
- 调用静态成员函数会导致运行时错误
- 在c++中调用静态成员的方法进行初始化
- 是在第一次调用静态成员函数之前初始化的静态类变量
- C++:在不同类的派生对象的基指针上调用静态成员函数
- 从继承的类实例调用静态成员
- 在对象上调用静态成员函数——有没有办法将其转化为编译器错误
- 调用c++静态成员函数的Objective-c包装器