ReadFile als Overlapped IO (RS232) und GetOverlappedResult

21/09/2010 - 15:04 von Martin Eckel | Report spam
Hallo,

in meinem Programm lade ich eine größere Menge Daten über den seriellen
Port und verarbeite diese gleichzeitig schon (soweit vorhanden).

Um die verfügbare Rechenleistung auszunutzen, aber auch nicht mit dem
Abholen der Daten ins Hintertreffen zu kommen, benutze ich zwei Threads,
der erste liest immer soviel Daten wie vorhanden und schreibt sie in
meinen Buffer, der zweite Thread (mit niedrigerer Prioritàt) verarbeitet
die vorhandenen Daten.

Nun dachte ich, es würde doch einfacher sein, ein asynchrones ReadFile
zu starten, den Empfang der Daten somit vollstàndig Windows zu überlassen.

Nun finde ich aber keine Möglichkeit, wàhrend einer laufenden Overlapped
IO herauszufinden, wieviele Daten bereits übertragen wurden und somit
schon im Buffer stehen.

Die API-Doku sagt zwar bei GetOverlappedResult:

lpNumberOfBytesTransferred [out]: A pointer to a variable that receives
the number of bytes that were actually transferred by a read or write
operation.

Jedoch scheint diese Variable doch nur gesetzt zu werden, wenn die
Overlapped IO beendet ist, solange GetOverlappedResult mit
ERROR_IO_PENDING beendet, steht der Wert auf 0.

Mach ich irgendwas falsch, oder ist es nicht möglich, wàhrend einer
laufenden Overlapped IO auf die bereits empfangenen Daten zuzugreifen
bzw. zu ermitteln, wieviele Daten bereits empfangen wurden?

Gruß,
Martin
 

Lesen sie die antworten

#1 Stefan Reuther
21/09/2010 - 20:03 | Warnen spam
Martin Eckel wrote:
Nun dachte ich, es würde doch einfacher sein, ein asynchrones ReadFile
zu starten, den Empfang der Daten somit vollstàndig Windows zu überlassen.

Nun finde ich aber keine Möglichkeit, wàhrend einer laufenden Overlapped
IO herauszufinden, wieviele Daten bereits übertragen wurden und somit
schon im Buffer stehen.

Die API-Doku sagt zwar bei GetOverlappedResult:

lpNumberOfBytesTransferred [out]: A pointer to a variable that receives
the number of bytes that were actually transferred by a read or write
operation.

Jedoch scheint diese Variable doch nur gesetzt zu werden, wenn die
Overlapped IO beendet ist, solange GetOverlappedResult mit
ERROR_IO_PENDING beendet, steht der Wert auf 0.



Genau so ist das. Das trifft zu, wenn du z.B. eine Datei oder Pipe
liest, und die zuende ist, bevor die mit ReadFile bestellte Anzahl Bytes
empfangen ist. GetOverlappedResult gibt dir das, was beim synchronen
ReadFile 'LPDWORD lpNumberOfBytesRead' ist.

Speziell für RS232 gibt es die Funktion mit dem eingàngigen Namen
ClearCommError, die dir eine Struktur COMSTAT befüllen kann. Dort
findest du in cbInQue die Anzahl bereits im Treiberpuffer befindlicher
Zeichen.

Ich hab im Besten Terminalprogramm der Welt[tm] in etwa sowas stehen:
COMSTAT cs; DWORD errors;
ClearCommError(hSerial, &errors, &cs);
DWORD bytesToRead = (cs.cbInQue == 0 ? 1 :
cs.cbInQue > sizeof(buffer) ? sizeof(buffer) :
cs.cbInQue);
DWORD read;
BOOL success = ReadFile(hSerial, &buffer, bytesToRead, &read,
&overlapped);
(aus dem Kopf zitiert)


Stefan

Ähnliche fragen