スレッドクラス

C++でWin32APIをラップしたようなライブラリを作ってるんだけど、スレッド機能の実装にて。

  • スレッドを開始するには_beginthreadex関数を使用する
  • 主な引数は呼び出す関数の開始アドレスとそれに渡す引数(void*型)

で、関数は__stdcall呼び出し規約である必要があって、戻り値がunsigned、引数がvoid*である必要がある。
そして重要なのは「仮想関数はアドレスが取れない」という事実。
ま、仮想関数が使いたければこんな風にやるわけだ。

class Thread {
public:
    virtual ~Thread() {}
    void start();
    virtual void run() = 0;
private:
    static unsigned __stdcall run_(void*);
};

void Thread::start() {
    // thisポインタをreinterpret_castしてrun_に渡す
    _beginthreadex(0, 0, run_, reinterpret_cast<void*>(this), 0, 0);
}

unsigned __stdcall Thread::run_(void* that) {
    // ポインタを戻す
    Thread* thread = reinterpret_cast<Thread*>(that);
    thread->run();
    _endthreadex(0);
    return 0;
}

これでめでたく問題解決。
あとはこのクラスを継承して、run関数をオーバーライドして、start関数を呼び出せば・・・
そう、Java風なスレッドクラスですね。


ちなみに
http://msdn2.microsoft.com/ja-jp/library/kdzttdcb.aspx
で_beginthreadex関数について読めます。