mercredi 14 novembre 2018

Pass class method as void function pointer (C++11)

I have an object which needs to interface with an existing C api to register an in interrupt (void function taking no arguments). I can attach the interrupt to the function function(). However, I want to be able to pass in arguments to the function, but that would change the function signature. I thought a way around that would be to create an object to store the parameters (and modify them as necessary), and then pass in a method (or similar). However, I haven't been able to figure out how to do that.

I've tried passing in a lambda as [=](){ std::cout << "a: " << a << "\n"; }, but it turns out lambdas with a capture can't be converted to function pointers. I've also tried a templated method (since it would get instantiated at compile time), but couldn't get it to work. I've seen some posts on SO talking about std::bind and std::function, but they often warn about virtual function overhead, which I'd like to avoid on an embedded platform for an ISR.

What is the best way to convert a paramterized function to a void(*)()?

#include <iostream>

void function() {
    std::cout << "Hello World!\n";
}

void attach_interrupt(void(*fn)()) {
    fn();
}

class A {
    int a;

public:
    A(int a) : a(a) {
        attach_interrupt(function); // This works as expected
        // attach_interrupt(method); // How do I make this work?
        // attach_interrupt(method2<a>);
    }

    void method() {
        // something requiring a and b
        std::cout << "a: " << a << "\n";
    }

    template<int a>
    void method2() {
        std::cout << "a: " << a << "\n";
    }
};

int main()
{
    const int PIN_1 = 0;
    const int PIN_2 = 1;
    const int PIN_3 = 2;

    A foo(PIN_1);
    A bar(PIN_2);
    A baz(PIN_3);

    return 0;
}

Aucun commentaire:

Enregistrer un commentaire