In a project that we intended to write in C , we use a C-library. This C library provides functions to register callbacks, that are called on each interrupt. We register our callbacks inside the constructor. So we basically have the following (simplified) structure:
OurClass::OurClass() {
//the registerISRCallback is the C function, that accepts as first parameter the pin,
//the interrupt is expected on and as second parameter a function pointer:
//void (*callbackFunction)(int number, int time)
registerISRCallback(SCLK, handle_interrupt);
}
void OurClass::handle_interrupt(int pin, int time) {
//example: Blink a Led on the instance-LedPin
}
the problem however is twofold:
- because it is a member function, the handle_interrupt method has the signature
void (OurClass::*)(int, int)
. Therefore it is not possible to use it like this. - this class can be instantiated multiple times, so using a singleton would also not work, because our callback may differ per instance (each instance could for example have a different LedPin.
are there any more solutions to use this C API function inside our class and keep the code clean and readable?
CodePudding user response:
Your class may integrate a static method that you pass as a C callback function (provided the calling conventions are made compatible; if not possible, wrap it in a pure C call).
In addition, let your class keep a static table of the created instances, in correspondence to the pins. When a callback is invoked, by knowing the pin, you will know which instance to activate.
CodePudding user response:
Create a C-style API (C outside, C inside), which itself registers as a single callback and allows to register multiple C callbacks. That would require some list-handling.
When the interrupt occurs, call all of them and let them decide whether they need to react, according to the callback parameters.
Alternatively, see the more luxurious proposal (mapping pin to one of multiple callbacks) in the comment by Story Teller, which basically does the detection of which callback is needed centrally.