メールスロットの非同期読込

[戻る]
ひろし 2005/03/15(火) 23:09:12
はじめまして。
メールスロットのデータを非同期で読み込みたいのですが、うまくいきません。

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;
}

PATIO 2005/03/16(水) 10:13:12
猫でもわかるプログラミングというホームページに
メールスロットの使い方に関するページがあったと思います。
Windows SDK編 第3部の第250章から何章か続けて読めばわかるのでは?

http://www.kumei.ne.jp/c_lang/index.html

このホームページはWin32APIを使った情報が充実していますのでお勧めです。
ブックマークしておく事をお勧めします。

PATIO 2005/03/16(水) 10:14:25
因みに手っ取り早く非同期にしたいならワーカースレッドでやった方が良いような気もし
ます。

PATIO 2005/03/16(水) 10:19:05
あと、GetLastErrorで得られた内容は.Netならツールのエラールックアップという機能が
あるので
自分で調べる癖をつけた方がいいです。

ひろし 2005/03/16(水) 11:51:56
PATIOさん。ありがとうございます。
とりあえず、上記のURLをみてやってみます。

ぼんぽこ 2005/03/16(水) 18:45:26
私も以前から気になっていたのですが、Windows ではスレッド終了やイベント、タイマ
ーなどの複数の事象をWaitForMulutipuleObject で一括待ち合わせができるようですが
メールスロットをこのAPIで待合わせをしている例を見たことがないので、大変興味
深いです。
「猫でもわかるプログラミング」でも、受信専用のスレッドで同期的に受信している例
は載っていますが、WaitForSingleObjectやWaitForMulutipuleObject を使用した非同期
の記載はないようですね。

 MSDN を見るとWaitForMulutipuleObject ではメールスロットを非同期で待合わせられ
るという記述はなんですよね。
それにもかかわらず、ReadFile には、
”Windows 95/98:<中略> メールスロット、名前付きパイプ、ディスクファイルに対
する非同期読み取り操作はサポートしていません。 ”
と記述があり、Windows2000 などでは、非同期読み取りができそうな記載があります。

ひろし 2005/03/16(水) 22:35:35
[[解決]]
ぽんぽこさんのおっしゃられるように、ReadFileでも非同期読み取りができそうに思った
のですが、残念ながらうまくいきませんでした。
ReadFileExとWaitForMulutipuleObjectExを使用したところ、何とか非同期で読み取りが
できるようになりましたので、こちらのAPIを使用して読み取りを行うことにします。

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