У меня есть объект, который должен взаимодействовать с существующим C api, чтобы зарегистрировать прерывание (функция void не принимает аргументов). Я могу прикрепить прерывание к функции function()
. Однако я хочу иметь возможность передавать аргументы функции, но это изменило бы сигнатуру функции. Я подумал, что можно создать объект для хранения параметров (и изменить их при необходимости), а затем передать метод (или аналогичный). Однако я не смог понять, как это сделать.
Я пытался передать лямбду как [=](){ std::cout << "a: " << a << "\n"; }
, но оказалось, что лямбда-символы с захватом не могут быть преобразованы в указатели функций. Я также попробовал шаблонный метод (так как он будет создан во время компиляции), но не смог заставить его работать. Я видел некоторые сообщения о SO, в которых говорится о std::bind
и std::function
, но они часто предупреждают о накладных расходах виртуальных функций, которых я бы хотел избежать на встроенной платформе для ISR.
Как лучше всего преобразовать параметризованную функцию в 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;
}
РЕДАКТИРОВАТЬ: Мое решение, вдохновленное выбранным ответом:
#include <iostream>
void attach_interrupt(int pin, void(*fn)()) {
fn();
}
// Free function, which works as an ISR
template <unsigned int IRQ, unsigned int IRQ2>
static void irqHandler()
{
std::cout << "IRQ: " << IRQ << "\n";
std::cout << "IRQ2: " << IRQ2 << "\n";
};
template <unsigned int PIN_1, unsigned int PIN_2>
class Handler {
private:
public:
Handler() {
void(*irq)() = &irqHandler<PIN_1, PIN_2>;
attach_interrupt(0, irq);
attach_interrupt(0, &handler_2);
}
// static member function can have its address taken, also works as ISR
static void handler_2() {
std::cout << "PIN_1: " << PIN_1 << "\n";
std::cout << "PIN_2: " << PIN_2 << "\n";
}
};
Handler<1, 2> a;
Handler<2, 3> b;
int main()
{
return 0;
}