2

任意の非静的クラス メソッドで AfxBeginThread を呼び出すにはどうすればよいですか? たぶん、ブーストバインドでできることはありますか?以下は、Microsoft から予想される使用法です (非静的メソッドを呼び出す例ですが、どのメソッドがハードコードされているかが示されています)。

UINT MyThreadProc( LPVOID pParam )
{
    CMyObject* pObject = (CMyObject*)pParam;

    if (pObject == NULL ||
        !pObject->IsKindOf(RUNTIME_CLASS(CMyObject)))
    return 1;   // if pObject is not valid

    // do something with 'pObject'

    return 0;   // thread completed successfully
}

// inside a different function in the program
...
pNewObject = new CMyObject;
AfxBeginThread(MyThreadProc, pNewObject);
4

3 に答える 3

4

AfxBeginThreadに渡すには静的関数が必要ですが、オブジェクトを呼び出す非常に単純な関数にすることができます。動作する可能性のあるテストされていないテンプレート関数を次に示します。

template<class T>
UINT __cdecl StartThread(LPVOID pParam)
{
    return ((T*)pParam)->MyThreadProc();
}
于 2011-10-21T17:38:39.630 に答える
2

コードサンプルは問題ありません。個別のスレッドで呼び出したい非静的クラス メソッドごとに、スレッド関数が必要になります。

boost:bind はまったく役に立ちません... AfxBeginThread は C++ テンプレート関数である必要があります。そうしないと、boost::bind または C++11 ラムダとキャプチャと互換性がありません。

代替手段の 1 つは、クラスとメソッドの組み合わせごとに列挙型を使用して構造体を作成することですが、それでもクラスとメソッドの組み合わせごとに列挙型とコールバック関数の両方に手動でコードを追加する必要があります。ただし、クラス/メソッドの組み合わせごとに個別のスレッド関数を作成するよりも、それほどコードは少なくありません。

struct ThreadData
{
  LPVOID object;
  enum ObjectCallType {
    Foo_Foo,
    Foo_Bar
  } objectCallType;
  LPVOID* param;
  ThreadData( LPVOID pobject, ObjectCallType poct, LPVOID* pparam=0 )
  :object(pobject), objectCallType(poct), param(pparam) {}
};

UINT MyThreadProc( LPVOID pParam )
{
    TheadData* thData = (ThreadData*)pParam;
    try 
    {
        switch( thData->objectCallType )
        {
            case ThreadData::Foo_Foo:
                Foo* foo = (Foo*)thData->object;
                foo->foo();
                break;
            case ThreadData::Foo_Bar:
                Foo* foo = (Foo*)thData->object;
                foo->bar( thData->param );
                break;
            default:
                throw std::exception("unhandled method call type");
        }
    }
    catch( std::exception& e )
    {
        std::cerr << e.what() << std::endl;
        delete thData;
        return 1;
    }
    delete thData;
    return 0;
}



//usage:
AfxBeginThread(MyThreadProc, new ThreadData(myFooObject,ThreadData::Foo_Bar,myFooCallParam));

ブーストの例 (未テスト):

boost::thread myFooFooThread( boost::bind( &Foo::Foo, myFooObject ) );
于 2011-10-21T17:21:00.573 に答える
0

この質問がかなり古いことは知っていますが、私の現在の状況に近いものです。Visual Studio 2008 プロジェクトで作成されたアプリケーションに取り組んでおり、すべての開始関数を回避したいと考えています。

私が見つけたのは、AfxBeginThread の 2 つの異なる呼び出しがあることです。もう 1 つは、最初のパラメーターとして CWinClass から派生したクラスを取り、ユーザー インターフェイス接続オブジェクトとワーカー スレッドの作成に使用されます。

私は2番目のオプションを選択しています。これは上記の質問でも機能しませんか?

于 2015-12-03T18:20:11.247 に答える