我有连接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,这在我的写入函数在控制台输出上写入之前就出现了。
我很绝望,所以我尝试了这个:
do
{
waitError = WaitForSingleObject(readReportEvent, timeout);
Sleep(500);
} while (waitError == WAIT_TIMEOUT && opened && readThreadNextStatus);
我不知道为什么,但现在它有效(不好,因为它有500毫秒的延迟)。
你怎么看?也许ReadFile和WriteFile并不同时工作?是什么原因引起的?我错过了什么吗?
答案 0 :(得分: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,因为此函数也会返回此值。
答案 1 :(得分:1)
您不应该在超时后重复ReadFile
,而是再次WaitForSingleObject
。你还有待阅读。穷人的循环(你可能应该改进它,以便用户可以中止它):
DWORD waitError;
do
{
waitError = WaitForSingleObject(ReportEvent, timeout);
}
while (waitError == WAIT_TIMEOUT);