クラスのメンバー関数をスレッドとして呼び出す方法

[戻る]
doru 2003/02/07(金) 09:22:46
VC++6.0(SP5)MFCのダイアログで作成しております。

1.以下のようなダイアログクラスのメンバー関数を1つ作成しました。
UINT C***Dlg::StartTread(LPVOID pParam);

2.そこでこの関数を同ダイアログのボタンからスレッドとして呼び出そうと思い
AfxBeginThread(StartTread,(LPVOID)0,THREAD_PRIORITY_NORMAL);
と記述してみたところ
error C2665: 'AfxBeginThread' : 2 のオーバーロードは 1 番目の引数を 'unsigned int 
(void *)' から要求の型に変換できません。(新しい機能 ; ヘルプを参照)
というエラーが出てしまいました。

3.何かおかしいと思いながらも下の用にキャストしてみましたが
AfxBeginThread((void*)StartTread,(LPVOID)0,THREAD_PRIORITY_NORMAL);
error C2440:〜〜となってしまいます。

クラスのメンバー関数をスレッドとして呼び出すことは無理なのでしょうか?

nasu 2003/02/07(金) 09:44:47
「メンバ関数 スレッド」で過去ログ検索

n [E-Mail] 2003/02/07(金) 09:44:54
クラスのstatic関数にして、
クラスメンバにアクセスするには、LPVOIDにthisを渡して対応する。

επιστημη 2003/02/07(金) 09:45:15
> クラスのメンバー関数をスレッドとして呼び出すことは無理なのでしょうか?
ひとひねりすれば、できます。

class XXX;

struct thread_param {
  XXX* instance;
  LPVOID pParam;
};

class XXX {
  UINT StartThread(LPVOID pParam) {
    ....
  }
  static UINT thread_entry(LPVOID arg) {
    thread_param* p = reinterpret_cast<thread_param*>(arg);
    return p->instance->StartThread(p->pParam);
  }
  void Onぼたん() {
    thread_param param;
    param.instance = this;
    pram.pParam = 0;
    AfxBeginThread(thread_entry,&param,THREAD_PRIORITY_NORMAL);
    ...
  }
  ...
};

doru 2003/02/07(金) 10:02:29
[[解決]]
>>nasuさん、nさん、επιστημηさん
有難うございます。

thread_param param;
param.instance = this;
pram.pParam = 0;

これはすごいですね、構造体ですか・・・
大変勉強になりました。
また、以降は過去ログを参照した後に質問いたします。

解決です。

επιστημη 2003/02/07(金) 17:28:30
#include <utility>
...

  typedef std::pair<XXX*,LPVOID> thread_param;

  static UINT thread_entry(LPVOID arg) {
    thread_param* p = reinterpret_cast<thread_param*>(arg);
    return p->first->StartThread(p->second);
  }

  void Onぼたん() {
    thread_param param(this,0);
    AfxBeginThread(thread_entry,&param,THREAD_PRIORITY_NORMAL);
    ...
  }

こっちの方が楽かな。

REE 2003/02/07(金) 17:42:08
επιστημηさん

素朴な疑問なんですが、こういう場合って
Onぼたん内のparamは少なくともthread_entryの終了時までは保証されるんでしょうか?

επιστημη 2003/02/07(金) 18:06:08
もちろん'されません'。
だからきわどいタイミングで危ないです。

paramはヒープから取得するか、global/staticにするが吉でしょう。

古いスレッドには追加発言できません。