C++: closure to pass member function as normal function pointer

一个人想着一个人 提交于 2019-12-13 14:23:30

问题


I'm trying to call a member function of an external library which takes a function pointer as a parameter:

Timer::every(unsigned long period, void (*callback)(void));

But unfortunately the parameter I want to pass is a member function:

void MyClass::the_method_i_want_to_pass(void);

Since I'm programming for the ATMega under Arduino (AVR) there is just limited support of c++11. My first approach raises a type error:

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();})
}

Compiler Output:

warning: warning: lambda expressions only available with -std=c++11 or -std=gnu++11 [enabled by default]

error: no matching function for call to ‘Timer::every(int, MyClass::MyClass()::__lambda0)’

  1. Are there other/better solutions?
  2. Concerning my current approach: (How) is it possible to pass a reference to a lambda when a function pointer is required?
  3. How can I find out if Arduino/AVR supports these lambdas (see "warning")?

回答1:


Your basic problem is your Timer library is poorky written: it should take void(*)(void*), void* at the least.

Without a pvoid or equivalent, you cannot pass any state other than the address in execution code to run the procedure at. As a method also rewuires a this pointer, you are out of luck.

Now, if your instance of MyClass is a singleton, you can get this from somewhere else.

Failing that, you need to make your own global state that lets you map from a particular callback to some state. If you have a limited number of MyClass and other consumers of Timer, you can have a few fixed functiins, and have them store their extra state globally.

This is all a hack. What follows is worse.

Write a dynamic library with some global state, and a void() interface. When you add a callback, duplicate that dynamic library, modify its global state at runtime, write it out as a differently named library, load it, and pass the pure callback function to your Timer class.

Or do the equvalent without a library by manually writing machine code and marking pages as execuable.

These are all poor solutions. Which leads me to a good one: find a better Timer. If they screwed up something that simple, the rest of the library is probably bad as well.



来源:https://stackoverflow.com/questions/24352785/c-closure-to-pass-member-function-as-normal-function-pointer

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!