本文介绍了HID - WaitForSingleObjectEx WAIT_TIMEOUT的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-01 13:30