Методы всегда содержат скрытый параметр this
для предоставления доступа к вызываемому объекту. Чтобы вызвать класс из обработчика прерываний, который ожидает C или C-подобное поведение вызова с соответствием 1:1 между перечисленными параметрами и необходимыми параметрами, вы должны обеспечить это C-подобное поведение. Это означает бесплатные функции или статические методы без скрытых параметров.
А это значит, что вы не можете назначить метод указателю на функцию, не углубляясь в предположения о неопределенном поведении.
Но у вас может быть статический метод или свободная функция, вызывающая метод объекта, если этот объект можно сделать доступным.
Данный
void (*func)(void*)
Там, где void *
является указателем на предоставленную пользователем управляющую информацию, простым решением является статический метод или свободная функция вида
void handlerCaller(void* userp)
{
ISRHandlerClass * handlerp = (ISRHandlerClass *) userp;
handlerp->isrhandler(); // tiny bit may be lost here to subclass look-up
}
А также
void isrhandler()
реализован, чтобы делать все, что, черт возьми, нужно делать ISRHandlerClass
или дочернему элементу ISRHandlerClass
.
Вы в значительной степени застряли с handlerCaller
или чем-то очень похожим, так что вы не можете избежать накладных расходов. Остальное зависит от того, насколько общим должен быть интерфейс ISR.
Простой универсальный базовый класс обработчика ISR:
class ISRHandlerClass
{
public:
virtual ~ISRHandlerClass()
{
}
// pure virtual to be implemented by specialized handler
virtual void isrhandler() = 0;
};
и такой же простой реализатор
class FooHandler: public ISRHandlerClass
{
public:
void isrhandler() //override tag if you've got 'em
{
// read Foo and store in buffer to be processed by lower priority task
}
};
Но если вы хотите отказаться от обобщения в пользу скорости, не беспокойтесь о подклассах. Вы жертвуете пространством для нескольких вызывающих обработчиков, если вам нужно более одного.
void FooHandlerCaller(void* userp)
{
FooHandler * handlerp = (FooHandler *) userp;
handlerp->isrhandler();
}
void BarHandlerCaller(void* userp)
{
BarHandler * handlerp = (BarHandler *) userp;
handlerp->isrhandler();
}
Or
template <class TYPE>
void handlerCaller(void* userp)
{
TYPE * handlerp = (TYPE *) userp;
handlerp->isrhandler();
}
Применение
class FooHandler
{
public:
void isrhandler()
{
// read Foo and store in buffer to be processed by lower priority task
}
};
void (*func)(void*) = handlerCaller<FooHandler>;
FooHandler handler;
void* instance = (void *)&handler;
person
user4581301
schedule
19.07.2016
this
, который, вероятно, сбивает вас с толку. Много полезной информации и советов здесь: isocpp.org/wiki/faq/pointers-to -члены - person user4581301   schedule 19.07.2016