asynchrones Lesen



  • Hallo,

    habe mir eine Klasse gebaut, die mit dem COM Port kommunizieren soll. Das Schreiben funktioniert auch, aber irgendwie empfange ich beim Lesen nichts.

    if (!ReadFile(m_PortHandle, Memory, 8/*MaxLength*/, &m_NumBytes, &overlapped))
    

    Bis dahin funktioniert ja auch alles. Danach prüfe ich mit

    if (!GetOverlappedResult(m_PortHandle, &overlapped, &m_NumBytes, FALSE))
    

    ob es da Probleme gab. Hier bricht er jedoch immer ab (durch Timeout) und nichts ist gelesen... 😞

    Irgendwer ne Idee?



  • Für meinen Geschmack sind das zu wenig Infos. Schlägt denn bereits ReadFile() fehl? Wenn ja, kommt dann auch ERROR_IO_PENDING von GetLastError() zurück? Wenn GetLastError() etwas anderes liefert: Was wird geliefert? Wie ist die OVERLAPPED-Struktur initialisiert? Ist sichergestellt, daß Daten eintreffen?



  • Ja, ReadFile schlägt fehl und GetLastError liefert ERROR_IO_PENDING.

    OVERLAPPED      overlapped;
    
        memset((void*)&overlapped, 0, sizeof(overlapped));
        overlapped.hEvent   = m_CompleteEvent;
    
        ResetEvent(m_CompleteEvent);
    

    Ob die Daten wirklich gesendet werden weiß ich nicht genau. Kann ich nur vermuten. Werde mal das ganze mit synkronem Lesen testen.

    Mal ne Frage: Wenn GetOverlappedResult nun erfolgreich beendet, wo liegen die Daten dann? In dem Speicher, den ich vorher bei ReadFile angegeben habe?

    [ Dieser Beitrag wurde am 17.12.2002 um 14:32 Uhr von Loggy editiert. ]



  • Jetzt habe ich was ganz komisches. Folgendes Programm enthält für "Error" 120, also "This function is not supported on this system." und das bei einem Win98 SE System... kann irgendwie nicht sein.

    #include <windows.h>
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
        HANDLE hCom = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
        int Error = GetLastError();
    
        COMMTIMEOUTS CommTimeout;
    
        CommTimeout.ReadIntervalTimeout         = 100;
        CommTimeout.ReadTotalTimeoutConstant    = 200;
        CommTimeout.ReadTotalTimeoutMultiplier  = 0;
        CommTimeout.WriteTotalTimeoutConstant   = 50;
        CommTimeout.WriteTotalTimeoutMultiplier = 50;
    
        SetCommTimeouts(hCom, &CommTimeout);
    
        char String[] = "ATD05171589333;\r";
        unsigned long   iNum = 0;
        int iError = WriteFile(hCom, String, sizeof(String) - 1, &iNum, NULL);
    
        char Data[256] = {0};
    
        iError = ReadFile(hCom, Data, 5, &iNum, 0);
    
        return 0;
    }
    

    [ Dieser Beitrag wurde am 17.12.2002 um 16:10 Uhr von Loggy editiert. ]



  • Folgendes Programm enthält für "Error" 120,

    Ich rate mal, daß von iError die Rede ist. Ich sehe in Deinem Code aber insgesamt 3 Zuweisungen. Was passiert also wo?

    HANDLE hCom = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
        int Error = GetLastError();
    

    Zunächst mal öffnest Du den Port falsch, es sollte "\\\.\\COM1" heißen. Spätestens bei Portnummern > 9 bekommst Du Probleme, vergleiche auch 115831 (Wo ist das gute alte "Q" geblieben?). Deine Variable iError bekommt nach CreateFile nur dann einen sinnigen Wert von GetLastError, wenn Du in hCom INVALID_HANDLE_VALUE stehen hast. Für alles != INVALID_HANDLE_VALUE ist der Inhalt von iError bedeutungslos.

    int iError = WriteFile(hCom, String, sizeof(String) - 1, &iNum, NULL);
    

    Diese Funktion gibt Dir nicht direkt den Fehlercode zurück. Den Fehlercode bekommst Du von GetLastError() (aber auch nur dann, wenn WriteFile fehlschlägt).

    iError = ReadFile(hCom, Data, 5, &iNum, 0);
    

    Das gilt dann auch für ReadFile.



  • Ne, ich meinte schon Error (steht ganz oben). Und ich checke die Werte ja über den Debugger direkt nach dem Aufruf. Aber gut, das mit dem INVALID_HANDLE_VALUE klingt logisch, auch wenn GetLastError da ruhig mal 0 zurückgeben könnte.

    Mal ne Frage: Wenn GetOverlappedResult nun erfolgreich beendet, wo liegen die Daten dann? In dem Speicher, den ich vorher bei ReadFile angegeben habe?



  • Ne, ich meinte schon Error (steht ganz oben).

    Ah, jetzt. Ich habe nicht gehen, daß da das führende "i" fehlt. Hinterhältig von Dir!. 😉

    In dem Speicher, den ich vorher bei ReadFile angegeben habe?

    Ja. Und wenn dieser Buffer auf dem Stack liegt und die Funktion vor der Beendigung von ReadFile/WriteFile verlassen wird, immer schön CancelIo() aufrufen.



  • Jetzt konnte ich es lösen. War ganz hinterhältig. Es lag daran, dass die falsche Baud rate eingestellt war. Habe nun auf 19200 gestellt und nun gehts.

    Danke nochmal für die Infos!


Anmelden zum Antworten