CLR「WindowsフォームAPL」CreateThread()実行エラー

[戻る]
とるまリンゴ 2006/05/10(水) 10:05:42
VC++2005 CLR「Windowsフォームアプリケーション」でプロジェクト作成環境に於いて、
CreateThread()を実行すると、下記実行エラーになってしまいます。

「Windowsフォームアプリケーション」で、Win32API CreateThread()を実行させる
のに必要な設定等をご教授願えないでしょうか。

尚、「Win32プロジェクト」でプロジェクト作成した場合には動作します。

<実行エラー・メッセージ>
 問題が発生したため、XXXX.exe を終了します。ご不便をお
 かけして申し訳ありません。
 作業途中であった場合、その情報は失われた可能性があります。

 エラー署名
   AppName: 4EEE60F3004700577C2166137248002E006500780065
   AppVer: 0.0.0.0
   ModName: unknown

<CreateThread()呼出コード>

    hwThread1 = CreateThread(
        NULL,
        0,
        (LPTHREAD_START_ROUTINE)Thread1,    // スレッド名
        &uiParam,                // パラメータ
        0,
        &dwThread1Id);

<開発環境>
   Windows XP SP2, Visual C++2005, 
   構成プロパティ「文字セット」=設定なし

とるまリンゴ 2006/05/10(水) 10:18:22
ランタイムライブラリの設定で補足します。

ランタイムライブラリの設定を変えてみたのですが、
同様に実行エラーになったり、ビルドエラーになったりで
うまくいきません。

<コンパイルが通らないもの>
  (1)「マルチスレッド デバッグ (/MTd)」
      error D8016 : コマンド ライン オプション '/MTd' と '/clr:pure' は
      同時に指定できません
  (2) 「マルチスレッド (/MT)」
      error D8016 : コマンド ライン オプション '/MT' と '/clr:pure' は
      同時に指定できません

<前述の実行エラーになってしまうもの>
  (3) 「マルチスレッド デバッグ DLL (/MDd)」
  (4) 「マルチスレッド DLL (/MD)」

シャノン 2006/05/10(水) 10:20:21
原因は分かりませんが、Windows フォームアプリなら、System::Threading::Thread を
使うべきでは無いでしょうか。

とるまリンゴ 2006/05/10(水) 16:21:14
  Delegateやらを使って下記対応しよとしたのですが、
  起動されたスレッド終了まで呼出側に処理がもどらないものしか作れて
  いません。Delegateで、平行に処理させる方法をどなたかご教授願えない
 でしょうか。

<コード>

 ●メインスレッド
  //戻り値とパラメータのあるDelegate(スレッド名+Delegateとした)
  delegate DWORD Thread1Delegate(LPVOID lpV);

  Thread1Delegate^ hp = gcnew Thread1Delegate(Thread1);
  //別スレッド Thread1起動 ↓ 呼出側が止まってしまうコード
  hp->Invoke((LPVOID)NULL);

 ●後から起動するスレッド
  DWORD __clrcall Thread1( LPVOID lpV )
  {
    while(TRUE)
    {
      System::Threading::Thread::Sleep(1000);    //一時テスト1秒ウエイト
      System::Diagnostics::Debug::WriteLine( "スレッド処理中" );
    }
  }

 > Windows フォームアプリなら、System::Threading::Thread を
 > 使うべきでは無いでしょうか。

 シャノンさん、アドバイスありがとうございます。
 こちらは、使い方調べている最中です。

とるまリンゴ 2006/05/10(水) 17:00:27
ネットで探してて多分、BeginInvoke()で非同期になるのかもと思い
試したが、下記失敗してしまいました。

> //別スレッド Thread1起動 ↓ 呼出側が止まってしまうコード
> hp->Invoke((LPVOID)NULL);

ここを、
  System::AsyncCallback ^ objCallbackFunc = nullptr;
  hp->BeginInvoke((LPVOID)NULL, objCallbackFunc, NULL); //<--★
に変えたら、★箇所ステップ実行時に下記のエラーが出てしまいました。

<実行エラーメッセージ>
  System.Runtime.Remoting.RemotingException' のハンドルされていない例外が
  mscorlib.dll で発生しました。
  追加情報: Pointer 型をリモート呼び出しで渡すことはできません。

シャノン 2006/05/10(水) 19:01:31
それはちょっと違う。
CreateThread に代わるコードは、ここの使用例を参考にしてください。

http://msdn2.microsoft.com/ja-jp/library/system.threading.thread(VS.80).aspx

とるまリンゴ 2006/05/11(木) 10:25:18
シャノンさんありがとうございます。

> CreateThread に代わるコードは、ここの使用例を参考にしてください。
> http://msdn2.microsoft.com/ja-jp/library/system.threading.thread(VS.80).aspx

これで、戻り値無し(void)かつ引数無し(void)に変更したら、動作しました。

戻り値有り、引数有りの場合は、調査中。

シャノン 2006/05/11(木) 10:36:55
> 戻り値有り、引数有りの場合は、調査中。

VC++ 2005 ならば、Thread クラスのコンストラクタの別形式を使うことで可能です。
詳しくは MSDN ライブラリを参照してください。

とるまリンゴ 2006/06/06(火) 12:52:39
[[解決]]
CreateThread()失敗原因はわからなかったのですが、
_beginthreadex()にして、プロジェクトの構成プロパティの
設定をいじっていたら(どの項目が効いたのか?ですが)
動作しました。

    hwThread1 = (HANDLE)_beginthreadex(
        NULL,
        0,
        Thread1,
        NULL,        //引数データ無し
        0,
        &dwThread1Id );

>> 戻り値有り、引数有りの場合は、調査中。
>
>VC++ 2005 ならば、Thread クラスのコンストラクタの別形式を使うことで可能です。
>詳しくは MSDN ライブラリを参照してください。

ご教授ありがとうございます。
この辺りまだ知識がないので、C++のクラス、コンストラクタ基礎から要勉強レベル
なので、まだ試せてません。

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