Я пытаюсь вызвать функцию-член внешней библиотеки, которая принимает указатель на функцию в качестве параметра:
Timer::every(unsigned long period, void (*callback)(void));
Но, к сожалению, параметр, который я хочу передать, является функцией-членом:
void MyClass::the_method_i_want_to_pass(void);
Поскольку я программирую для ATMega под Arduino (AVR), поддержка c ++ 11 ограничена. Мой первый подход вызывает ошибку типа:
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();})
}
Выход компилятора:
предупреждение: предупреждение: лямбда-выражения доступны только с -std = c ++ 11 или -std = gnu ++ 11 [включено по умолчанию]
ошибка: нет соответствующей функции для вызова call Timer :: every (int, MyClass :: MyClass () :: __ lambda0) ’
Ваша основная проблема ваша Timer
библиотека написана плохо: надо брать void(*)(void*), void*
по крайней мере.
Без pvoid или его эквивалента вы не можете передать любое состояние, кроме адреса в коде выполнения, для запуска процедуры. Как метод также reuuuers this
указатель, вам не повезло.
Теперь, если ваш экземпляр MyClass
это одиночка, вы можете получить this
откуда-то еще
В противном случае вам нужно создать собственное глобальное состояние, которое позволяет отображать конкретный обратный вызов в какое-то состояние. Если у вас есть ограниченное количество MyClass
и другие потребители Timer
Вы можете иметь несколько фиксированных функций, и они могут хранить свое дополнительное состояние во всем мире.
Это все взломать. Что следует, хуже.
Напишите динамическую библиотеку с некоторым глобальным состоянием и void()
интерфейс. Когда вы добавляете обратный вызов, продублируйте эту динамическую библиотеку, измените ее глобальное состояние во время выполнения, запишите ее как библиотеку с другим именем, загрузите ее и передайте функцию чистого обратного вызова вашей Timer
учебный класс.
Или сделайте эквивалент без библиотеки, вручную написав машинный код и пометив страницы как исполняемые.
Это все плохие решения. Что приводит меня к хорошему: найди лучшее Timer
, Если они испортили что-то такое простое, остальная часть библиотеки, вероятно, тоже плохая.