メソッドには、呼び出されているオブジェクトへのアクセスを提供するための隠しフィールドthis
が常に含まれています。リストされたパラメータと必要なパラメータとの間に1対1の対応関係を持つCまたはCのような呼び出し動作が必要な割り込みハンドラからクラスを呼び出すには、Cのような動作を行わなければなりません。つまり、隠されたパラメータを持たないフリー関数または静的メソッドを意味します。
これは、未定義の動作についての仮定を掘り下げずに関数ポインタにメソッドを割り当てることができないことを意味します。
しかし、静的メソッドやフリー関数を使用すると、オブジェクトを利用できるようにすることができれば、オブジェクトに対してメソッドを呼び出すことができます。
がvoid *
は、ユーザーにより供給制御情報へのポインタである
void (*func)(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;
メソッドは常に、おそらくあなたをトリップされ、隠し 'this'パラメータを持っています。役に立つ情報やヒントはこちら:https://isocpp.org/wiki/faq/pointers-to-members – user4581301