はじめまして。
メールスロットのデータを非同期で読み込みたいのですが、うまくいきません。
CreateMailSlotのハンドルでReadFileを行うとGetLastError()=121で復帰し、
CreateFileのハンドルでReadFileを行うとGetLastError()=87で復帰します。
また、WaitForSingleObject()では、別のプロセスからメールスロットに
何か送信しても、制御が戻ってきません。
どうすれば、メールスロットを非同期で読込ができるようになるのか教えて
いただけないでしょうか。
環境はXP(SP2)+VS.NET(VC++)です。
<以下はソースです。>
int _tmain(int argc, _TCHAR* argv[])
{
DWORD rtn, nSiz = 0 ;
HANDLE hOpenHdl, hMailHdl ;
OVERLAPPED ovMailSlot;
char strMailSlot[64];
char strWk[32];
// メールスロットの作成
sprintf( strMailSlot, \\\\.\\mailslot\\Slot0 );
hOpenHdl = CreateMailslot( strMailSlot, 0, 0, NULL );
if( hOpenHdl == NULL ) return 0;
// メールスロットを開く
hMailHdl = CreateFile( strMailSlot, GENERIC_READ, (FILE_SHARE_READ |
FILE_SHARE_WRITE), NULL, OPEN_EXISTING, (FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_OVERLAPPED), NULL );
if( hMailHdl == NULL ) return 0;
memset( &ovMailSlot, 0, sizeof(ovMailSlot) );
ovMailSlot.Offset = 0 ;
ovMailSlot.hEvent = CreateEvent( NULL, FALSE, FALSE, Evt_MailSlot );
if( ovMailSlot.hEvent == NULL ) return 0;
// メールスロットの読込
rtn = ReadFile( hMailHdl, strWk, sizeof(strWk), &nSiz, &ovMailSlot );
if( rtn != TRUE ){
printf( ReadFile failure Rtn=%d,Err=%d\n, rtn, GetLastError() );
}
// メールスロットへの書込み待ち
rtn = WaitForSingleObject( ovMailSlot.hEvent, INFINITE );
return 0;
}
猫でもわかるプログラミングというホームページに
メールスロットの使い方に関するページがあったと思います。
Windows SDK編 第3部の第250章から何章か続けて読めばわかるのでは?
http://www.kumei.ne.jp/c_lang/index.html
このホームページはWin32APIを使った情報が充実していますのでお勧めです。
ブックマークしておく事をお勧めします。
因みに手っ取り早く非同期にしたいならワーカースレッドでやった方が良いような気もし
ます。
あと、GetLastErrorで得られた内容は.Netならツールのエラールックアップという機能が
あるので
自分で調べる癖をつけた方がいいです。
PATIOさん。ありがとうございます。
とりあえず、上記のURLをみてやってみます。
私も以前から気になっていたのですが、Windows ではスレッド終了やイベント、タイマ
ーなどの複数の事象をWaitForMulutipuleObject で一括待ち合わせができるようですが
メールスロットをこのAPIで待合わせをしている例を見たことがないので、大変興味
深いです。
「猫でもわかるプログラミング」でも、受信専用のスレッドで同期的に受信している例
は載っていますが、WaitForSingleObjectやWaitForMulutipuleObject を使用した非同期
の記載はないようですね。
MSDN を見るとWaitForMulutipuleObject ではメールスロットを非同期で待合わせられ
るという記述はなんですよね。
それにもかかわらず、ReadFile には、
”Windows 95/98:<中略> メールスロット、名前付きパイプ、ディスクファイルに対
する非同期読み取り操作はサポートしていません。 ”
と記述があり、Windows2000 などでは、非同期読み取りができそうな記載があります。
ぽんぽこさんのおっしゃられるように、ReadFileでも非同期読み取りができそうに思った
のですが、残念ながらうまくいきませんでした。
ReadFileExとWaitForMulutipuleObjectExを使用したところ、何とか非同期で読み取りが
できるようになりましたので、こちらのAPIを使用して読み取りを行うことにします。