C++ C++;:闭包将成员函数作为普通函数指针传递
我试图调用外部库的成员函数,该库将函数指针作为参数:C++ C++;:闭包将成员函数作为普通函数指针传递,c++,arduino,atmega,C++,Arduino,Atmega,我试图调用外部库的成员函数,该库将函数指针作为参数: Timer::every(unsigned long period, void (*callback)(void)); 但不幸的是,我要传递的参数是一个成员函数: void MyClass::the_method_i_want_to_pass(void); 因为我是在Arduino(AVR)下为ATMega编程,所以对c++11的支持有限。我的第一种方法引发了一个类型错误: void MyClass::the_method_i_want_
Timer::every(unsigned long period, void (*callback)(void));
但不幸的是,我要传递的参数是一个成员函数:
void MyClass::the_method_i_want_to_pass(void);
因为我是在Arduino(AVR)下为ATMega编程,所以对c++11的支持有限。我的第一种方法引发了一个类型错误:
void MyClass::the_method_i_want_to_pass() {...}
MyClass::MyClass() {
// constructor
Timer *timer = new Timer();
timer->every(500, [this](){this->the_method_i_want_to_pass();})
}
编译器输出:
警告:警告:lambda表达式仅适用于-std=c++11或-std=gnu++11[默认启用]
错误:对“Timer::every(int,MyClass::MyClass():::\uu lambda0)”的调用没有匹配的函数
你的基本问题是你的
计时器
库写得很糟糕:它至少需要void(*)(void*),void*
如果没有pvoid或等效项,则无法传递除执行代码中的地址以外的任何状态来运行该过程。由于一种方法也会重新创建一个这个指针,所以您运气不好
现在,如果您的MyClass
实例是一个单例,那么您可以从其他地方获得this
如果做不到这一点,您需要创建自己的全局状态,使您能够从特定回调映射到某个状态。如果您有数量有限的MyClass
和Timer
的其他使用者,您可以有一些固定的函数,并让它们全局存储它们的额外状态
这完全是胡闹。接下来的情况更糟
编写一个具有某种全局状态的动态库,以及一个void()
接口。添加回调时,复制该动态库,在运行时修改其全局状态,将其写出为不同名称的库,加载它,并将纯回调函数传递给Timer
类
或者,在没有库的情况下,通过手动编写机器代码并将页面标记为可执行页面来实现等值
这些都是糟糕的解决方案。这让我想到了一个好方法:找到一个更好的计时器。如果他们搞砸了这么简单的事情,库的其余部分可能也不好。你的编译器支持std::mem_fn吗?
,它的c++11思想使用了一个类似的端口。这个问题没有意义。这就像说:“我妻子想让我带西红柿回家。我有一盒指甲和一条面包。1.有更好的解决办法吗?2.我怎样才能取悦我的妻子?3.我怎样才能找到一个接受指甲和面包作为西红柿的妻子?”我不明白你的意思@KerrekSB。在我看来,对于第三方图书馆的局限性,这是一个明确的问题。这正是关闭图书馆的目的。。。将作用域/状态封装到函数中。您的建议是什么?谢谢您的回复!我想我会从一个黑客开始,直到我可以用更好的东西取代它。