问题描述
我使用ReadFileEx()从通用HID设备连续读取,然后通过调用WaitForSingleObjectEx()。我的想法是,当WaitForSingleObjectEx返回WAIT_IO_COMPLETION时,我再次调用ReadFileEx来启动另一次读取。但是,即使调用传递给ReadFileEx的回调函数,WaitForSingleEx也总是返回WAIT_TIMEOUT。为什么?从我读到的内容中我了解到,当IO完成并且调用回调时,WaitForSingleObjectEx应该返回WAIT_IO_COMPLETION。
这些是我的代码的重要部分:
I read continuously from generic HID device using ReadFileEx() and then by calling WaitForSingleObjectEx(). My idea is that when WaitForSingleObjectEx returns WAIT_IO_COMPLETION I call again ReadFileEx to initiate another read. However WaitForSingleEx returns always WAIT_TIMEOUT even when my callback passed to ReadFileEx is called. Why? From what I read I understand that WaitForSingleObjectEx should return WAIT_IO_COMPLETION when the IO is completed and when the callback is called.
These are the important parts of my code:
void THid::THid( void) {
EventRead = CreateEvent(NULL, TRUE, FALSE, NULL);
OverlappedRead.hEvent = EventRead;
OverlappedRead.Offset = 0;
OverlappedRead.OffsetHigh = 0;
InitiateReportIn = true;
// the code continues...
// Handle = CreateFile(.....)
}
void THid::Execute(void) {
if (InitiateReportIn) {
if (ReadFileEx(Handle, &ReportBuffer, 65, &OverlappedRead, ReportInCallback)) {
InitiateReportIn = false;
}
}
switch (WaitForSingleObjectEx(EventRead, 1, TRUE)) {
case WAIT_IO_COMPLETION:
InitiateReportIn = true;
break;
default:
break;
}
}
VOID CALLBACK THid::ReportInCallback(
_In_ DWORD dwErrorCode,
_In_ DWORD dwNumberOfBytesTransfered,
_Inout_ LPOVERLAPPED lpOverlapped
) {
DWORD ReadBytes;
if (dwErrorCode != ERROR_SUCCESS) {
return;
}
if (!GetOverlappedResult(Handle, lpOverlapped, &ReadBytes, FALSE)){
return;
}
//InitiateReportIn = true; // If I uncomment this, reading works fine
// Do something with report
}
推荐答案
include "stdafx.h"
#include <iostream>
#include <string>
#include <windows.h>
using namespace std;
static int stepnow = 0;
void __stdcall CompletionRoutine(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, OVERLAPPED* lpOverlapped)
{
cout<<"CompletionRoutine has been called: bytes read " << dwNumberOfBytesTransfered << " step: " << stepnow++ <<endl;
}
bool MyReadFileEx(LPCTSTR FileName)
{
bool bRet = false;
char Buf[28] = {0};
OVERLAPPED overlap;
#define OVERLAPPED
#if defined(OVERLAPPED)
HANDLE hFile = ::CreateFile(FileName,
GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN|FILE_FLAG_OVERLAPPED, NULL);
#else
HANDLE hFile = ::CreateFile(FileName,
GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
#endif
if(hFile!=INVALID_HANDLE_VALUE)
{
::memset(&overlap , 0, sizeof(overlap));
BOOL bReadResult = ::ReadFileEx(hFile, Buf, sizeof(Buf), &overlap, CompletionRoutine);
if(!bReadResult && ERROR_HANDLE_EOF==::GetLastError())
{
bReadResult = TRUE;
}
while(bReadResult && stepnow < 4)
{
DWORD dwResult = ::WaitForSingleObjectEx(hFile, INFINITE, TRUE);
switch (dwResult)
{
case WAIT_OBJECT_0:
{
cout<< "WAIT_OBJECT_O " << stepnow << endl ;
}
break;
case WAIT_IO_COMPLETION:
{
bReadResult = ::ReadFileEx(hFile, Buf, sizeof(Buf), &overlap, CompletionRoutine);
cout<< "WAIT_IO_COMPLETION " << stepnow << endl ;
}
break;
case WAIT_TIMEOUT:
{
cout<< "WAIT_IIMEOUT " << stepnow << endl ;
}
break;
}
bRet = bReadResult ? true : false;
}
::CloseHandle(hFile);
}
return bRet;
}
int _tmain(int argc, _TCHAR* argv[])
{
bool bResult = MyReadFileEx(L"C:\\Temp\\abc1.txt");
const string str = string("Read ") + string(bResult ? "Succeeded" : "Failed") + string(".");
cout<< str <<endl;
system("pause");
return 0;
}
这篇关于HID - WaitForSingleObjectEx WAIT_TIMEOUT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!