7 years ago.

Correct construction for callback() on a member function.

In mbed 5 I have a callback function that looks like this:

static void myCallback(OtherClass *classPointer);

...i.e. a static function that takes a pointer to a class as its single parameter.

In my code I can construct a callback to this as follows:

callback(myCallback, theClassPointer);

This works fine. Unfortunately, I now need the function myCallback to be a member function, not a static function, so its definition has become:

class MyClass {
...
protected:
    void myCallback(OtherClass *classPointer);
}

I can't, for the life of me, figure out what the callback construction has to be now, from the gazillion options that callback.h presents. Can anyone help please?

Rob

You may have a look at this : https://developer.mbed.org/forum/bugs-suggestions/topic/27062/. The answer of Sarah (6.11.2016) helped me a lot for a similar question

posted by yota news 21 Apr 2017

Thanks for the link. As far as I can tell, in Sarah's case she has either a callback to a static function that takes a single parameter or a callback to a member function that takes no parameters. The bit that is confounding me is how to construct a callback to a member function that takes a single parameter.

posted by Rob Meades 21 Apr 2017

1 Answer

6 years, 12 months ago.

Hello Rob,
Since I was not able to figure out how to pass member function arguments to the callback function the myCallback member function of MyClass takes no arguments. The OtherClass pointer is passed through the MyClass constructor:

#include "mbed.h"
#include "rtos.h"

Thread      thread;
DigitalOut  led1(LED1);
DigitalOut  led2(LED2);

class OtherClass
{
public:
    OtherClass(DigitalOut* out) :
        _out(out) {};
    ~OtherClass(void) {}

    DigitalOut* digitalOut() {
        return _out;
    }
private:
    DigitalOut*  _out;
};

class MyClass
{
public:
    MyClass(OtherClass* other) :
        _other(other) {}
    ~MyClass(void) {}

    void myCallback(void) {
        while(1){
            *_other->digitalOut() = !*_other->digitalOut();
            wait(1);
        }
    }
private:
    OtherClass*  _other;
};

int main(void) {
    OtherClass  otherClass(&led2);
    MyClass     myClass(&otherClass);

    thread.start(callback(&myClass, &MyClass::myCallback));  // callback using member function
    while(true) {
        led1 = !led1;
        wait_ms(500);
    }
}

Wow, that's a neat solution. It seems so complex to do what is conceptually the simplest thing in C when one moves to C++ land. Thankfully you've made me realize that I'm an idiot: the reason my static functions had to have a parameter was because they needed access to a member variable. Since I've now made them all members I can dispense with the parameter! Despite that, I think the use case remains and I still wonder if there is some formulation of callback() that allows a member function with a parameter to be called back.

posted by Rob Meades 21 Apr 2017