我需要一个函数来从串行端口读取数据,或者如果在时间间隔内没有数据则返回。例如。在 GNU/Linux 上你可以使用poll()
orselect()
+read()
。 Windows 中有类似的东西吗?
下面是我尝试过的:它应该可以工作,但是功能获取重叠结果() http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms683209(v=vs.85).aspx要么有问题,要么没有很好的文档记录;它没有报告任何内容,而不是读取的字节数(甚至不是零,例如,如果我不初始化lpNumberOfBytesTransferred
参数,它只是包含垃圾).
// NOTE: the `file` should be opened in non-blocking mode
long ReadData(HANDLE file, char* buf, long szbuf, int msTimeout){
OVERLAPPED ReadState = {0};
ReadState.hEvent = CreateEvent(0, true, false, "☠");
if (!ReadState.hEvent){
PrintLastErr();
return -1;
}
unsigned long BytesRead = 0; //number of bytes was read
if (!ReadFile(file, buf, szbuf, &BytesRead, &ReadState)){
// This creates a reading event. Below we wait for it to complete, and cancel on timeout
if (GetLastError() != ERROR_IO_PENDING){
PrintLastErr();
return -1;
}
// No, I can't use WaitForSingleObject(), it exits with disregard to whether
// reading is ongoing or no more data left (e.g. in case of a serial port).
while(1) {
std::this_thread::sleep_for(std::chrono::milliseconds( msTimeout ));
unsigned long ret;
puts("Getting result");
if (!GetOverlappedResult(file, &ReadState, &ret, false)
&& GetLastError() != ERROR_IO_INCOMPLETE){
PrintLastErr();
return -1;
}
printf("result is %lu\n",ret);
if(ret == BytesRead){
return BytesRead;
}
BytesRead = ret;
}
} else { //completed immediately
printf("Bytes read %i\n");
assert(BytesRead <= LONG_MAX);
return (long)BytesRead;
}
}