Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 丢失带有GetOverlappedResult的数据?_C++_Winapi_Io_Serial Port - Fatal编程技术网

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-开始新的读取,读取新的字节数

如果我将GetOverlappedResult切换到blocking(传递TRUE),它每次都会工作。 如果我把我的线程切换到只有当我知道那里有数据时才读取,它每次都会工作

但是如果那里没有数据,当那里有数据时,它似乎“丢失”了数据,我的读取量参数
dwRead
显示了正确的读取字节数(可以通过端口监视器看到它的读取),但字节没有存储在我的字符*中

我经常读到错误

我做错了什么


我不想使用标志,我只想使用
ReadFile
GetOverlappedResult
,我应该能够用我拥有的代码完成这一点。。。。。。。我想问题正是数据丢失的原因。。。它丢失的原因是,传递到readfile的bytes参数是父线程中的一个局部变量。由于是本地的,它会在每个周期重新初始化,因此在我再次进入读取后,跳过读取文件并转到重叠的结果,我现在可能使用不同的内存区域

your
memset(字节,'\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中得到了一些东西