2

Windows スレッド プール (QueueUserWorkItem()) でクラスのメンバー関数を呼び出す必要があります。

残念ながら、これは、メンバー関数ポインターを引数として QueueUserWorkItem() に渡すことによって直接行うことはできません。

難しいのは、複数のメンバー関数を呼び出し可能にする必要があり、それらのシグネチャが異なることです (ただし、すべて void を返します)。

これを機能させるには、おそらくいくつかの抽象化レイヤーを追加する必要がありますが、これにアプローチする方法がわかりません。何か案は?

4

2 に答える 2

1

これは役立つかもしれません。tr1::function () と tr1::bind を使用して、さまざまな呼び出しを「結合」できます。

   #include <iostream>
   #include <tr1/functional>
   using namespace std;
   using namespace tr1;

   class A
   {
   public:
      void function(int i) { cout << "Called A::function with i=" << i << endl; }
   };

   void different_function(double c) {
       cout << "Called different_function with c=" << c << endl;
   }


   int main(int argc, char* argv[])
   {
      function<void()> f = bind(different_function, 3.14165);
      f();

      A a;
      f = bind(&A::function, a, 10);
      f();

      return 0;
   }

関数オブジェクトのアドレスは、単一の呼び出し可能なオブジェクトとして渡すことができます (必要なアドレスは 1 つだけです)。

于 2011-07-12T15:26:55.033 に答える
0

例:クラスに次を追加します。

char m_FuncToCall;

    static DWORD __stdcall myclass::ThreadStartRoutine(LPVOID myclassref)
    {
      myclass* _val =  (myclass*)myclassref;
      switch(m_FuncToCall)
      {
         case 0:
          _val->StartMyOperation();
         break;
       }
       return 0;
    }

キューに追加するメンバーを作成してから

void myclass::AddToQueue(char funcId)
 {
    m_FuncToCall=funcId;
   QueueUserWorkItem(ThreadStartRoutine,this,WT_EXECUTEDEFAULT);
 }

または作成する

typedef void (*MY_FUNC)(void);
    typedef struct _ARGUMENT_TO_PASS
    {
     myclass* classref;
     MY_FUNC func;

    }ARGUMENT_TO_PASS;

その後

void myclass::AddToQueue(MY_FUNC func)
{
   ARGUMENT_TO_PASS _arg;
   _arg.func = func;
   _arg.classref = this;
    QueueUserWorkItem(ThreadStartRoutine,&_arg,WT_EXECUTEDEFAULT);
}

さらに説明が必要な場合は、お気軽にお問い合わせください:)

編集: 2番目の例ではThreadStartRoutineを変更する必要があります。また、渡される引数を保持するように構造体を変更することもできます。

于 2011-07-12T15:15:22.010 に答える