1

Wiiリモコンとの接続があります

handle = CreateFile(didetail->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if(handle != INVALID_HANDLE_VALUE) {
    opened = true;
    readReportEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    memset(&readOverlapped, 0, sizeof(readOverlapped));
    readOverlapped.hEvent     = readReportEvent;
    readOverlapped.Offset     = 0;
    readOverlapped.OffsetHigh = 0;

    writeReportEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    memset(&writeOverlapped, 0, sizeof(writeOverlapped));
    writeOverlapped.hEvent    = readReportEvent;
    writeOverlapped.Offset    = 0;
    writeOverlapped.OffsetHigh = 0;
}

私は常に新しいメッセージのためにこのハンドルを読むスレッドを持っています:

while(opened && readThreadNextStatus){
    memset (readBuff, 0, 22);
    BYTE* ptrbuff = new BYTE[22];
    int readfile = ReadFile(handle, readBuff, reportLength, NULL, &readOverlapped);
    if(readfile == 0 && GetLastError() == ERROR_IO_PENDING){
        DWORD waitError;
        do 
        {
            waitError = WaitForSingleObject(readReportEvent, timeout);
        } while (waitError == WAIT_TIMEOUT && opened && readThreadNextStatus);

        if(opened && readThreadNextStatus){
            DWORD read = 0;
            if(waitError == WAIT_OBJECT_0){
                GetOverlappedResult(handle, &readOverlapped, &read, TRUE);
            }
            ResetEvent(readReportEvent);
            memcpy(ptrbuff, readBuff, 22);

        cout << "Read:  ";
        coutHex(ptrbuff);
        }
    }
}

私の書き込み関数:

if(opened){
    if(!WriteFile(handle, buff, reportLength, NULL, &writeOverlapped)){
        if(GetLastError() != ERROR_IO_PENDING){
            close();
        }
    }
    WaitForSingleObject(writeReportEvent, timeout);
    DWORD write = 0;
    GetOverlappedResult(handle, &writeOverlapped, &write, TRUE);
    ResetEvent(writeReportEvent);
}
cout << "Write: ";
coutHex(buff);

コンソール出力:

Connection established
Write: 15- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0-
Read:   0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0-
Read:   0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0-
Write: 15- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0-
Read:   0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0-
Write: 15- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0-
Read:   0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0-
Read:  20- 0- 0-10- 0- 0-49-ff-ff-ff-ff-ff-ff-ff-ff-ff-ff-ff-ff-ff-ff-ff-
Write: 15- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0-
Read:   0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0-
Write: 15- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0
Read:   0- 0-
0- 0-
- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0- 0-

coutHexは、受信したデータを常に16進形式で出力します。正しいデータを取得することもありますが、配列に00 00 00 00 00 00 00 00 00 ...0000のみがロードされることもあります。

書き込みを行うと、常に00のみを含むレポートが返されます。これは、書き込み関数がコンソール出力に書き込みを行う前に表示されます。

私は必死だったので、これを試してみました:

do 
            {
                waitError = WaitForSingleObject(readReportEvent, timeout);
                Sleep(500);
            } while (waitError == WAIT_TIMEOUT && opened && readThreadNextStatus);

理由はわかりませんが、現在は機能しています(500msの遅延があるため、問題ありません)。

どう思いますか?たぶん、ReadFileとWriteFileは同時に機能しませんか?

これの原因は何ですか?私は何か見落としてますか?

4

2 に答える 2

2

いくつかの追加の問題があります:

  • 手動リセットイベント(CreateEvent(NULL、TRUE、FALSE、NULL))を作成し、代わりに自動リセットイベント(CreateEvent(NULL、FALSE、FALSE、NULL))を作成します。

  • ReadFileがFALSEを返し、GetLastErrorの値がERROR_IO_PENDINGであるかどうかを確認します。この場合、イベント(WaitForSingleObject)を待ちます。

  • WaitForSingleObjectがWAIT_OBJECT_0を返す場合は、GetOverlappedResultを呼び出します。

    GetOverlappedResultを使用する場合、この関数もこの値を返すため、lpNumberOfBytesReadを渡す必要はありません。

于 2010-11-13T21:49:14.873 に答える
1

ReadFileタイムアウト後に繰り返すのではなく、WaitForSingleObjectもう一度繰り返すことになっています。まだ未読です。貧乏人のループ(ユーザーがそれを中止できるように、おそらくそれを改良する必要があります):

DWORD waitError;
do
{
    waitError = WaitForSingleObject(ReportEvent, timeout);
}
while (waitError == WAIT_TIMEOUT);
于 2010-11-13T22:35:20.997 に答える