C++ 丢失带有GetOverlappedResult的数据?
我有一个线程不断寻找新数据,如果数据不在串行缓冲区中,C++ 丢失带有GetOverlappedResult的数据?,c++,winapi,io,serial-port,C++,Winapi,Io,Serial Port,我有一个线程不断寻找新数据,如果数据不在串行缓冲区中,ReadFile和GetOverlappedResult似乎告诉我有数据,它读取了数据,但没有将其传输到我的缓冲区中 func read() { if(state == 0) { memset(bytes, '\0', sizeof(amount_to_read)); readreturn = ReadFile(h, bytes, amount_to_read,NULL, osReader);
ReadFile
和GetOverlappedResult
似乎告诉我有数据,它读取了数据,但没有将其传输到我的缓冲区中
func read()
{
if(state == 0)
{
memset(bytes, '\0', sizeof(amount_to_read));
readreturn = ReadFile(h, bytes, amount_to_read,NULL, osReader);
if(readreturn <= 0)
{
errorcode = GetLastError();
if(errorcode != ERROR_IO_PENDING)
{
SetEAIError(ERROR_INTERNALERROR);
return -1;
}
}
}
if (GetOverlappedResult(h, osReader, &dwRead, FALSE) == false)
{
errorcode = GetLastError();
if (errorcode == ERROR_IO_INCOMPLETE || errorcode == 0)
{
if(dwRead > 0)
{
return 1;
}
//timeout
SetEAIError(ERROR_EAITIMEOUT);
return -1;
}
else
{
//other error
SetEAIError(ERROR_WIN_ERROR);
return -1;
}
}
else
{
//read succeded, check if we read the amount required
if(dwRead != amount_to_read)
{
if(dwRead == 0)
{
//nothing read, treat as timeout
SetEAIError(ERROR_EAINOREAD);
return -1;
}
else
{
//memcpy_s(bytes, sizeof(bytes), readbuf, dwRead);
SetEAIError(ERROR_PARTIALREAD);
*_bytesRead = dwRead;
return -1;
}
}
else
{
if(strlen((char*)bytes) == 0)
{
//nothing read, treat as timeout
SetEAIError(ERROR_EAINOREAD);
return -1;
}
//memcpy_s(bytes, sizeof(bytes), readbuf, dwRead);
*_bytesRead = dwRead;
return 0;
}
}
}
func read()
{
如果(状态==0)
{
memset(字节,'\0',sizeof(读取量));
readreturn=ReadFile(h,字节,读取量,NULL,osReader);
if(readreturn 0)
{
返回1;
}
//超时
SetEAIError(错误为EAITIMEOUT);
返回-1;
}
其他的
{
//其他错误
SetEAIError(错误\胜利\错误);
返回-1;
}
}
其他的
{
//读取成功,检查我们是否读取了所需的金额
如果(dwRead!=读取量)
{
如果(dwRead==0)
{
//未读取任何内容,视为超时
SetEAIError(错误\ EAINOREAD);
返回-1;
}
其他的
{
//memcpy_s(字节、大小(字节)、readbuf、dwRead);
设置错误(部分读取错误);
*_bytesRead=dwRead;
返回-1;
}
}
其他的
{
如果(strlen((char*)字节)==0)
{
//未读取任何内容,视为超时
SetEAIError(错误\ EAINOREAD);
返回-1;
}
//memcpy_s(字节、大小(字节)、readbuf、dwRead);
*_bytesRead=dwRead;
返回0;
}
}
}
这就是错误代码的含义:
- ERROR_TIMEOUT-将状态切换为1,以便不再读取,这将再次调用
GetOverlappedResult
- INTERNALERROR,ERROR\u EAINOREAD-它将状态重置为0
- 错误\u PARTIALREAD-开始新的读取,读取新的字节数
dwRead
显示了正确的读取字节数(可以通过端口监视器看到它的读取),但字节没有存储在我的字符*中
我经常读到错误
我做错了什么
我不想使用标志,我只想使用
ReadFile
和GetOverlappedResult
,我应该能够用我拥有的代码完成这一点。。。。。。。我想问题正是数据丢失的原因。。。它丢失的原因是,传递到readfile的bytes参数是父线程中的一个局部变量。由于是本地的,它会在每个周期重新初始化,因此在我再次进入读取后,跳过读取文件并转到重叠的结果,我现在可能使用不同的内存区域yourmemset(字节,'\0',sizeof(amount_to_read))
是错误的,除非您只想清除缓冲区的第一个n
字节,其中n
是amount\u to\u read
变量类型的大小。这可能就是为什么你认为那里有数据,但实际上没有标记,不应该是字节大小。。。我认为那里有数据的原因是因为getoverlappedresults将dwRead DWORD设置为6,而我的数组都是零(还要指出的是,我知道我正在使用strlen来测试这一点,我的数据没有零,所以这是一个快速攻击,strlen返回第一个空字符,通常不会工作,但这不是我的问题,我也在我的观察窗口中验证过)好的,最后一个问题,state
在这个上下文中更新了哪里?我问这个问题是因为您显然需要开始读取,但是除了eval之外,state
不在这个代码中。我可以假设它不在这个范围内?无论您是否有意,这看起来您实际上是在试图发出一个重叠的异步读取请求,t当GetOverlappedResult上的自旋循环尝试从中读取数据时。我通常使用可变io,或者更好的是,IOCP,但您不这样做肯定有原因。我必须说,我不使用这些的原因是因为我不熟悉它们…:(-并且根据返回数据包在主循环外部更新yes状态(请参阅底部的错误代码说明)所以你说的话听起来像我在做的,读一次,然后等待它超时或给我数据,如果它超时,我再读一次,如果它还没有超时,那么我继续调用get OverlappedResults,如果它给我数据,我希望它在那里(它没有)从我过去做过的串行通信来看,这总是足够的,你是说不足够吗?不用担心不熟悉,每个人都有时间学习。在Windows中旋转循环IO通常是个坏主意。有时是必要的,但通常很少。关于方法的文档相当不错。我假设你的程序是正确的单线程从外观上看,这使得异步io具有一定的挑战性(并非不可能,但仍然很困难)。这肯定会导致问题。每个io操作都需要(a)自己的重叠严格,以及(b)只要请求“在那里”,就有内存。我很高兴您从doc=P中得到了一些东西