重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

<プログラム環境>
Windows XP
VC++6.0
MFC AppWizard(exe)
ダイアログベース

<目的>
COMポートでバイナリデータの送受信を行う

<プログラムの仕様>
1.ダイアログの「受信開始」ボタンを押す
   データ受信開始の合図"0x01"を相手機器に送る
2.相手機器がデータを永遠と送信してくる
3.データを永遠と受信する
4.ダイアログの「受信終了」ボタンを押す
   データ受信終了の合図"0x02"を相手機器に送る
5.相手機器がデータ送信を止める
6.受信終了

<質問>
上記のプログラム仕様を満たすには、マルチスレッドにしないといけないと思うのですが(データの送信と受信でスレッドを分ける)、具体的に何をどうすればマルチスレッドになるのか分かりません。
マルチスレッドに必要な関数、
プログラムの全体的な流れなど、
基本的な部分を教えてください。

宜しくお願いします。

A 回答 (2件)

Win32APIのCreateThread()を呼べばスレッドが起動します。



参考書としては
「マルチスレッドプログラミング入門」ISBN:4756116825
をお勧めします。

簡単な例としては下記のような感じ
スレッドを複数動作させる場合にはmutexとか必要ですが一個だけなら排他は考えなくても実害は無いと思います。
スレッドに渡すデータはローカル変数をアドレス渡ししてはいけません。
スレッドが渡された変数を参照した時点で呼び出し元の処理が終了して領域が開放されてしまっているいる可能性があります。
スタックではなくヒープのアドレスを渡すようにした方が良いです。

 HANDLE threadHandle ;//スレッドハンドル
 DWORD thid ;    //スレッドID
 // Dataはスレッドに渡すデータ(型は何でもよい)のアドレス:必要なければNULL

 threadHandle = CreateThread(0,0,(LPTHREAD_START_ROUTINE)ThreadFunc,(void *)Data,0,&thid) ;

 if (threadHandle == NULL) return ;
 CloseHandle(threadHandle) ; // スレッドが起動したらハンドルを閉じます

// スレッド動作する関数
void ThreadFunc(DATA_t *Data) // ←ポインタ変数を1個受け取れる
{
 ・・スレッドの処理本体:省略・・
}

DATA_tは必要なら適時定義してください。
必要なければvoid *で良いです。

この回答への補足

buriburi3様、有難うございます。

ご指摘頂いた通りだと思うのですが、以下のようにコーディングしました。
OnButton()はダイアログのボタンを押すと実行されます。

void CMyDlg::OnButton()
{
 HANDLE hThread;//スレッドハンドル
 DWORD dwThreadID;//スレッドID
 DWORD Data;
 hThread = CreateThread(0,0,(LPTHREAD_START_ROUTINE)ThreadFunc,&Data,0,&dwThreadID);
}
void ThreadFunc(DWORD *Data)
{
}

コンパイルするとhThread = ...の行に対して以下のエラーが出ます。
error C2440: 'type cast' : '' から 'unsigned long (__stdcall *)(void *)' に変換することはできません。
スコープ内でこの名前を持つ関数でターゲット型に一致するものはありません。

何が原因でこのエラーが出るのでしょうか?

宜しければご指摘お願い致します。

補足日時:2008/06/20 16:07
    • good
    • 0

まず「永遠と」は「延々と」のつもりかな。



それで仕様を読む限りでは、相手機器も同じプログラムの中でシミュレーションするのでなければマルチスレッドは必要ないように思うけど。
マルチスレッドにしてもあまり書きやすくはないんじゃないかな。

仕様の書き方を変えると
0.ダイヤログを表示して「受信表示」ボタンを待つ
1.ダイアログの「受信開始」ボタンを押されたら
   データ受信開始の合図"0x01"を相手機器に送る
2.受信待ちをする(ここで「受信終了」ボタンも待つ)
3.データを受信する(2と繰り返し)
4.ダイアログの「受信終了」ボタンを押されたら
   データ受信終了の合図"0x02"を相手機器に送る
5.相手機器がデータ送信を止めたことを確認する(?)
6.受信終了
ですね。(5は必要ないかも)

ここで必要なのは、2でCOMポートの受信と「受信終了」ボタンを同時に待つ複数待ちです。これはWIN32APIだとMsgWaitForMultipleObjects等が使えますし、コンソールアプリケーションではselect等も使えますが、MFCでのやり方は覚えてません。
COMポート通信を非同期アクセスにする必要があるかも。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!