5

まず、いくつかの背景:(
注:私は非.NET Win32の土地にいますが、これは実際にはC ++の質問です)

非同期操作がいつ完了したかを知るためにコールバック関数を登録する必要があるサードパーティのAPIを使用しています。コールバックを使用する必要があります。それを回避する方法はありません。

非OOP実装は、次のようになります。

void __stdcall MyCbFcn(int value)
{
   do something with 'value'...
}

API_RegisterCallback(MyCbFcn);

かなり標準的なもの。

しかし...
私のコードはOOPであり、複数のインスタンスがコールバックをrxしているため、コールバックはそれを登録したオブジェクトにルーティングする必要があります。

人々がこれを行うことを知っているので、コールバックには通常、次のようなユーザー変数が含まれます。

void __stdcall MyCbFcn(int value, U32 user)
{
   do something with 'value'...
}

API_RegisterCallback(MyCbFcn, someUserValue);

より具体的には、OOPと組み合わせると、このユーザー引数を使用してコンテキストに戻ることができます:(
簡潔にするためにインラインで記述):

class MyClass
{
public:
   MyClass()
   {
      API_RegisterCallback(MyClass::StaticCbFcn, (U32)this);
   }

private:
   static void __stdcall StaticCbFcn(int value, U32 user)
   {
      MyClass* pThis = (MyClass*)user;
      pThis->InstanceCbFcn(value);
   }
   void InstanceCbFcn(int value)
   {
      ... do some work in context ...
   }
}

しかし、私のAPIはユーザー引数を備えていません:(

だから今私の質問:
どうすれば文脈に戻ることができますか?

100個の異なるコールバックの「プール」を定義し、それらをオブジェクトの作成時に割り当てるなど、ちょっと大雑把なことを考えましたが、それは本当のハックのようです。

明らかな解決策...たとえばJavaScriptを使用している場合:)...無名関数を使用することですが、AFAIKC++にはそのようなものはありません。

任意のアイデアをいただければ幸いです。

4

1 に答える 1

2

「100個の個別のコールバック」が実際に実行できる唯一のことであるため、関数アドレスを識別パラメーターとして使用します。定数パラメーターを使用して、さまざまな関数をテンプレートとして実装すると役立つ場合があります。

template < unsinged N >
void StaticCbFcn( int value )
{
    map[ N ].InstanceCbFcn( value );
}
于 2012-07-20T16:22:58.323 に答える