方法总是包含一个隐藏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();
}
或者
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;