题
我有一个连接Wiimote
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总是以十六进制格式打印收到的数据。有时我会得到正确的数据,但有时只用00 00 00 00 00 00 00 00 00 00 ... 00 00 00 00 00 00 00 00 00 00
我经历了这一点,当我写作时,我总是会收回一个报告,其中仅包含00的报告,这在我的写入功能使写入控制台输出之前出现。
我很绝望,所以我尝试了一下:
do
{
waitError = WaitForSingleObject(readReportEvent, timeout);
Sleep(500);
} while (waitError == WAIT_TIMEOUT && opened && readThreadNextStatus);
我不知道为什么,但是现在起作用(不正确,因为它具有500ms的延迟)。
你怎么看?也许ReadFile和WriteFile不同时工作?
是什么原因造成的?我错过了什么?
解决方案
还有一些其他问题:
创建手动重置事件(createEvent(null,true,false,null))而不是自动reset事件(createEevent(null,false,false,false,null))。
检查ReadFile是否返回false,并且GetLasterRor的值是error_io_pending,在这种情况下,请等待事件(WaitforsingLeoBject)。
如果WaitForsingLeleObject返回Wait_Object_0,则您调用GetOverLappedResult。
如果您使用GetOverLappedResult,则不需要通过LPNumberOfBytesRead,因为此功能也返回此值。
其他提示
你不应该重复 ReadFile
超时,但是 WaitForSingleObject
再次。您仍然需要阅读。可怜的人的循环(您可能应该完善它,以便用户可以中止它):
DWORD waitError;
do
{
waitError = WaitForSingleObject(ReportEvent, timeout);
}
while (waitError == WAIT_TIMEOUT);
不隶属于 StackOverflow