Forum: PC-Programmierung Probleme mit WriteFile(),das Overlapped aufgerufen wird


von Markus B. (Firma: MTU-FN) (ditsche)


Lesenswert?

Hi zusammen,

Ich hab' mal wieder ein weiteres Problem mit der RS232.

Ich möchte mit VS 2005 unter Vista ein Programm schreiben, das Daten 
über die Rs sendet und empfängt. Und zwar "Overlapped".

Das Lesen ist kein Problem. das Funktioniert einwandfrei.

Nur mit dem Schreiben hab' ich ein Problem.
Wenn ich WriteFile() aufruf, kommt sie gleich mit false zurück, wie sie 
das auch soll und was verständlich ist, da sie auch nicht zaubern kann.
Danach prüfe ich mit "GetLastError()" ob die Schnittstelle noch am 
Senden ist.
Das liefert mir dann auch immer ERROR_IO_PENDING zurück.
Dann warte ich mit WaitForSingleObject() darauf, dass das Event gesetzt 
wird. Wenn das passiert ist, müsste ja alles klar sein.
Aber die Variable, in die WriteFile() schreibt, ist dann immer noch "0".
Und es sind auch keine Daten aus der Schnittstelle herausbekommen.

Hier ist erstmal das öffnen des Ports:
------------------------------------------------------------------------ 
--
HANDLE Port::OpenPort(char* s1)
{
        OVERLAPPED sOverlapped;
  OVERLAPPED sOverlapped_W;
  HANDLE hEvent;
  HANDLE hEvent_W;
        HANDLE hComm;
  DCB sDcb;
         //Overlapped-Struct löschen, wie von Microsoft empfohlen
        ZeroMemory(&sOverlapped,sizeof(OVERLAPPED));
  ZeroMemory(&sOverlapped_W,sizeof(OVERLAPPED));
         //Events erstellen
  sOverlapped.hEvent = CreateEvent(NULL,false,false,NULL);
  sOverlapped_W.hEvent = CreateEvent(NULL,true,false,NULL);

        hComm = INVALID_HANDLE_VALUE;
         //Port öffnen
  hComm = CreateFileA(s1,GENERIC_READ | GENERIC_WRITE, 0, NULL,
                             OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);

        GetCommState(hPort,&sDcb);
         //Parameter anpassen (komplett ohne Handshake)
  sDcb.BaudRate = CBR_38400;
  sDcb.ByteSize = 8;
  sDcb.Parity = NOPARITY;
  sDcb.fParity = false;
  sDcb.fDsrSensitivity = false;
  sDcb.StopBits = ONESTOPBIT;
  sDcb.fDtrControl = DTR_CONTROL_DISABLE;
  sDcb.fRtsControl = RTS_CONTROL_DISABLE;
  sDcb.fNull = true;

  SetCommState(hPort,&sDcb);
}

Und hier nun meine Funktion zum Senden:
------------------------------------------------------------------------ 
---
int Port::Send(char *buffer, int iBytesToWrite)

   DWORD dwBytesWritten = 0;

   if(WriteFile(hPort, buffer, iBytesToWrite, &dwBytesWritten,
                &sOverlapped_W))
   {
     return dwBytesWritten;
   }
   else
   {
     if(ERROR_IO_PENDING == GetLastError())
     {
                    //Ist noch am Senden...
       cout << "Braucht Noch" << endl;
       if(WAIT_OBJECT_0 ==
                        WaitForSingleObject(sOverlapped_W.hEvent,1000))
       {
                            //Jetzt wurde der Event gesetzt
                            //Hier kommt das Programm auch immer an
         cout << "Müsste gesendet haben" << endl;
                            //Problem!!!!!!!!!!!!!!1!!!!
          //Jetzt hat aber "dwBytesWritten" den Wert 0
                           return dwBytesWritten;
                            //Problem!!!!!!!!!!!!!!!!!!!!
       }
       else
       {
         cout << "Timeout 1000ms" << endl;
       }

     }
     else
     {
       cout << "Es ist ein Fehler aufgetreten" << endl;
       return 0;
     }
   }
}
------------------------------------------------------------------------ 
---
So steht's auch im MSDN. Darum hab' ich keine Ahnung, was ich noch 
vergessen oder falsch gemacht hab'.

Falls ihr noch was wissen müsst, sagt bitte bescheid.

Wär euch dankbar, wenn mir einer von euch "Cracks" :-) helfen könnte.

Danke schon mal

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du musst noch die Funktion GetOverlappedResult aufrufen, sonst wird 
Dein dwBytesWritten nie verändert.

von Tobi H. (tobi-) Benutzerseite


Lesenswert?

Benutz mal GetOverlappedResult um die echt geschiebene Bytezahl zu 
bekommen
http://msdn2.microsoft.com/en-us/library/ms683209(VS.85).aspx

Edit: Zu langsam, aber immerhin mit Link ;)

von Markus B. (Firma: MTU-FN) (ditsche)


Lesenswert?

Hey Danke, das ging ja schnell.

Ok, hab's gemacht. Jetzt passt's. Muss nur noch rausfinden ob wirklich 
was gesendet wird.

Dann hätt ich nur noch ne Verständnisfrage:

Wenn ich WriteFile() ohne Overlapped aufrufe dann schreibt es ja auch in 
die Variable.

Macht sie des in meinem Beispiel nur wegen dem Overlapped nicht?

Nochmals vielen Dank

von FBI (Gast)


Lesenswert?

Direkt aus der M$-Doku zu WriteFile:
1
"If lpOverlapped is not NULL, lpNumberOfBytesWritten can be NULL.
2
If this is an overlapped write operation, you can get the number
3
of bytes written by calling GetOverlappedResult."
CU

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.