И снова ReadFile + COM порт
От: lomezych  
Дата: 17.06.04 08:29
Оценка:
Значит так

Есть такой код

bool MyFrame::Read(char* buffer, int& nr)
{
    DWORD dwBytesRead = 0,
          dwCommStatus;
    
    BYTE  bChar;
    
    OVERLAPPED osWait = {0};      
    osWait.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if ( osWait.hEvent == NULL )
    {
        wxMessageBox("Cannot create event. Read thread aborted");
        return true;
    }

    BOOL fWaitingForEventTimeout = FALSE;
    
    nr = 0;
    
    PurgeComm(m_hPort,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
    SetCommMask (m_hPort, EV_RXCHAR);

    do 
    {
        if ( !fWaitingForEventTimeout )
        {       
            if ( !WaitCommEvent(m_hPort, &dwCommStatus, &osWait) )
            {           
                if ( GetLastError() != ERROR_IO_PENDING ) 
                {
                    wxMessageBox("Error in WaitCommEvent");
                    return true;
                }    
            }
            else wxMessageBox("Waiting for event..");
        }
        else *main << "Already waiting for event..\n";
        
        switch (WaitForSingleObject(osWait.hEvent, 10000))
        {
            case WAIT_OBJECT_0:
                {
                    *main << "Event happened.\n";
                    fWaitingForEventTimeout = FALSE;
                    ResetEvent(osWait.hEvent);
                    do 
                    {
                        if ( !ReadFile(m_hPort, &bChar, 1, &dwBytesRead, &m_OverlappedRead) )
                        {
                            if ( GetLastError() != ERROR_IO_PENDING ) 
                            {
                                wxMessageBox("Error in ReadFile");
                                return true;
                            }
                            else 
                            {
                                switch (WaitForSingleObject(m_OverlappedRead.hEvent, 300))
                                {
                                    case WAIT_OBJECT_0:
                                        {
                                            // add error checking for this func
                                            GetOverlappedResult(m_hPort, &m_OverlappedRead, &dwBytesRead, FALSE);
                                            ResetEvent(m_OverlappedRead.hEvent);
                                            if ( dwBytesRead == 1 )
                                            {
                                                buffer[nr] = bChar;
                                                nr++;
                                                *main << "Byte recieved: " << bChar << "\n";
                                                break;
                                            }
                                            *main << "Object signaled but no byte recieved, hmm\n";
                                            break;
                                        }
                                    case WAIT_TIMEOUT:
                                        {
                                            CloseHandle(osWait.hEvent);
                                            *main << "Timeout. Nothing else to read.\n";
                                            return false;
                                        }
                                    /*     
                                    default:
                                        {
                                            *main << "Mingi jama... Mollame edasi\n";
                                            ResetEvent(m_OverlappedRead.hEvent);
                                            break;
                                            // return true;
                                        }
                                    */
                                }
                            }           
                        }
                        else
                        {
                            if ( dwBytesRead == 1 )
                            {
                                *main << "ReadFile returned immidiately:";
                                buffer[nr] = bChar;
                                nr++;
                                *main << " recieved: " << nr << " byte " << bChar << "\n"; 
                            }
                            else 
                            {
                                // сюда ходить не надо
            *main << "ReadFile returned immidiately and nothing else to read.\n";
                                break;
                            }    
                        }
                    } while (dwBytesRead);
                    
                    break;
                }
            
            case WAIT_TIMEOUT:
                {
                    *main << "event never occured.. exiting\n";
                    fWaitingForEventTimeout = TRUE;
                    break;
                }
            default:
                {
                    *main << "shit happened while waiting for event\n";
                    break;
                }
        }
    } while (fWaitingForEventTimeout);

return false;



проблема в том, что бывает так, что ReadFile возвращается сразу, что говорит о том что операция успешно выполнена, те байтик почитали сразу как бы ( или хочется думать, что это должно быть так ) и тогда не надо идти в WaitForSingleObject. Но на самом деле dwBytesRead == 0. Как такое побороть??
... << Rsdn@Home 1.1.4 beta 1 >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.