Entwickler-Ecke

Windows API - ReadFile -Differenzen unter Win98 und WinXP


Jakob Schöttl - Mi 04.04.07 21:52
Titel: ReadFile -Differenzen unter Win98 und WinXP
Hallo,

Hintergrund:
Ich bin dabei ein Programm zu entwickeln, das über COM1 Kontakt zu einer Auswertmaschine aufnimmt. Das Schreiben in die Schnittstelle funzt tadellos. Das Lesen aber bei Win98 nur, wenn auch etwas in der Schnittstelle steht.


Aufruf der API-Funktion ReadFile:
Win98 -> Wenn kein Zeichen in der Schnittstelle ist, dann wartet ReadFile so lange, eines da ist. Erst dann geht das Programm weiter.
WinXP -> Wenn kein Zeichen in der Schnittstelle ist, dann wird der Ausgabeparameter lpNumberOfBytesRead auf 0 gesetzt, und weiter gehts.


Das was XP macht ist natürlich besser - das Programm bleibt nicht hängen, sondern läuft weiter, und ich kann auf das Nicht-Vorhanden-Sein des Bytes reagieren.

Was ich bräuchte, wäre also eine Funktion, die mir sagt, ob Bytes in der Schnittstelle sind, oder nicht. Dann wäre gewährleistet, das das Programm auch unter 98 nicht verreckt (, weil ich dann ReadFile nur aufrufe, wenn eben welche da sind).

Oder gibt es noch eine andere Möglichkeit?


Hier bei msdn [http://msdn2.microsoft.com/en-us/library/aa365467.aspx] eine beschreibung von ReadFile, falls das weiterhilft

Quelltext
1:
2:
3:
4:
5:
6:
7:
BOOL ReadFile(
  HANDLE hFile,
  LPVOID lpBuffer,
  DWORD nNumberOfBytesToRead,
  LPDWORD lpNumberOfBytesRead,
  LPOVERLAPPED lpOverlapped
);


Bernhard Geyer - Mi 04.04.07 21:54
Titel: Re: ReadFile -Differenzen unter Win98 und WinXP
user profile iconJakob Schöttl hat folgendes geschrieben:
Oder gibt es noch eine andere Möglichkeit?

Es gibt Komponenten die sich diesem Problem angenommen haben und eine Eventbasierte Lösung bieten. Du bekommst Events wenn Fehler auftreten, Daten anliegen, Deine Daten gesendet wurden, ...


Jakob Schöttl - Mi 04.04.07 22:04

Kennst du solche Komponenten? Hast du Links?
Danke schon mal!


Narses - Mi 04.04.07 22:51

Moin!

Pack das Lesen in einen Thread und verwende eine (programm-)interne Zeichenqueue dafür. ;)

cu
Narses


Jakob Schöttl - Do 05.04.07 17:36

Danke user profile iconNarses!
Dass ich das richtig verstehe: Ich mach einen Thread, der die ganze Zeit in einer Schleife liest, und die chars in ein Array (= Queue) speichert?


Narses - Do 05.04.07 23:22

Moin!

Ja, so würde ich das machen. Klassisch wird dafür ein Ringpuffer verwendet (also z.B. ein Array mit einem Schreib- und einem Lesezeiger, die bei i > Length(array) wieder bei 0 anfangen). Puffer "groß genug" machen und überlegen, was passieren soll, wenn die Zeiger "kollidieren" (-> weitermachen und überschreiben oder Abbruch und Fehler).

cu
Narses


Jakob Schöttl - Fr 06.04.07 11:54


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TLeseThread.Execute;
var chr: char;
begin
  While not Terminated do
  begin
    if FSerial.TryReadChar(chr) then
    begin
      c := chr;
      Synchronize(ausgabe);
    end;
  end;
end;

so, das wäre schön!

Aber jetzt erst ist mir eingefallen, dass ich ja nicht nur lesen, sondern auch schreiben will! Das ist ein Problem, weil ich kann nicht mit zwei Objekten auf die Schnittstelle zugreifen.

Wie gesagt, bei Win98 bleibt das TryReadChar so lange hängen, bis ein Character da ist.

Ich muss mir wohl was anderes überlegen.