![]() |
Zugriffsverletzung bei(Kommunikations)Timeout mit overlapped
Moin zusammen.
Ich möchte von einem USB-Geräte lesen und es beschreiben können. Dazu benutze ich DriverX von Tetradyne. Das funktioniert soweit auch alles wunderbar. Wenn ich nun vom Gerät lesen möchte, dieses aber nicht antwortet bleibt meine Anwendung in der Read Funktion 'stecken'. Ich möchte also sowas wie ein Timeout haben. Der Treiber bietet keine Möglichkeit einen Timeout einzustellen. Die einzige Chance die ich sehe ist es mit 'overlapped' zu realisieren. 'Overlapped' war mit bis jetzt noch kein Begriff. Die Dokumentation gibt leider nicht viel her: Zitat:
Nun habe ich ein wenig rumgegooglet und habe versucht, das was ich gefunden habe umzusetzten:
Code:
Wenn ich nun aber das Programm ausführe und auf ein Element der Overlapped Struktur zugegriffen wird, kommt es zu einer Zugriffsverletzung:
procedure InitOverlapped(var Overlapped : lpOverlapped);
begin Overlapped.Offset := 0; Overlapped.OffsetHigh := 0; Overlapped.Internal := 0; Overlapped.InternalHigh := 0;} Overlapped.hEvent := CreateEvent(nil,True,False,''); end; function ReceiveCommand(...):.. var ... Overlapped : lpOverlapped; begin InitOverlapped(Overlapped); Ret := UsbBulkRead(deviceHandle, 0, 0, 0, @USBcb, 8, BytesReceived, Overlapped); Zitat:
Wer kann bei mir für Aufklärung sorgen? Vielen Dank für jegliche Hinweise und Hilfe! |
Re: Zugriffsverletzung bei(Kommunikations)Timeout mit overla
Das ist die uebliche Verwechslung von Pointer auf Struktur und Struktur.
Delphi-Quellcode:
Der Eventname ist verdaechtig ein anonymer Event verwendet nil statt ''.
procedure InitOverlapped(var Overlapped: TOverlapped);
begin Overlapped.Offset := 0; Overlapped.OffsetHigh := 0; Overlapped.Internal := 0; Overlapped.InternalHigh := 0; Overlapped.hEvent := CreateEvent(nil,True,False,''); end; Ist ein ManualReset-Event noetig? Hier setzt sich der Fehler fort.
Delphi-Quellcode:
Wird denn nach UsbBulkRead auf den Event gewartet? Wenn nicht wird die Funktion verlassen und Overlapped wird zerstoert. Es muss sichergestellt werden das Overlapped solange existiert bis UsbBulkRead den Event nicht mehr triggert.
function ReceiveCommand(...):..
var ... Overlapped: TOverlapped; begin InitOverlapped(Overlapped); Ret := UsbBulkRead(deviceHandle, 0, 0, 0, @USBcb, 8, BytesReceived, @Overlapped); |
Re: Zugriffsverletzung bei(Kommunikations)Timeout mit overla
Erstmal vielen Dank für die schnelle Antwort.
Zitat:
Zitat:
Zitat:
Nochmals vielen Dank! |
Re: Zugriffsverletzung bei(Kommunikations)Timeout mit overla
LPOVERLAPPED ist in C ein "OVERLAPPED *", also ein Zeiger auf ein OVERLAPPED-Record. In Delphi gibt es OVERLAPPED als TOverlapped bereits. LPOVERLAPPED waere dann "type LPOVERLAPPED = ^TOverlapped;". Damit hast du nie ein Record deklariert und die Variable Overlapped ist ein uninitialisierter Zeiger und zeigt in den Wald. Natuerlich bekommst du damit eine Schutzverletzung.
Das mit dem warten ob etwas gelesen wurde, sollte sich realisieren lassen. SleepEx sollte genuegen. Es muss allerdings danach das UsbBulkRead (vermutlich mit CancelIo) abgebrochen werden, falls SleepEx den Timeout signalisiert. Korrektur: WaitForSingleObject. Besser ist allerdings du schreibst einen Thread der das handhabt. Noch besser du findest jemanden der mit solchen Sachen vertraut ist. Ich bin es, aber ich habe keine Zeit. |
Re: Zugriffsverletzung bei(Kommunikations)Timeout mit overla
Zitat:
Zitat:
Die jetzige Lösung funktioniert in sofern, dass die UsbBulkRead-Funktion sofort wieder verlassen wird und die Applikation solange an WaitForSingleObject wartet bis die Daten empfangen wurden bzw. der Timeout erreicht wurde. Werden die Daten gesendet, werden diese auch korrekt empfangen. Werden keine Daten gesendet und somit der Timeout erreicht, kann ich das am Rückgabewerte sehen. Soweit, so gut. Nur das Abbrechen der UsbBulkRead Funktion mit CancelIO scheint nicht zu klappen. Der Rückgabewert ist FALSE. Mit GetLastError bekomme ich den Rückgabewert 6. Das bringt mich zu einer vielleicht etwas dummen Frage: Gibt es für Delphi irgendwo die defines bzw. 'Konstantenzuweisungen' für die Rückgabewerte? Habe bei WaitForSingleObject beispielsweise gesehen, dass WAIT_TIMEOUT = 258 sein müsste und 0 scheint wohl WAIT_OBJECT_0 zu sein. Bei C hat gibt es ja meistens Header Dateien, in denen die defines/macros für die Rückgabewerte eingetragen sind. Leider bin ich mit diesen (Windows API ?) Funktionen auch noch nicht so vertraut. Woran könnte es liegen, dass es mit CancelIO nicht funktioniert? Ist es sicher, dass UsbBulkRead wie andere I/O Funktionen abgebrochen werden muss? Zur Vollständigkeit, so sieht es im Moment bei mir aus (zwei mal Read, das Zweite mal nur wenn das Erste erfolgreich war):
Delphi-Quellcode:
Kann mir jemand Literatur zu Grundlagen für Thread- und API-Programmierung empfehlen? Habe bis jetzt das hier gefunden:
procedure InitOverlapped(var Overlapped : lpOverlapped);
begin Overlapped.Offset := 0; Overlapped.OffsetHigh := 0; Overlapped.Internal := 0; Overlapped.InternalHigh := 0; Overlapped.hEvent := CreateEvent(nil,False,False,nil); end; function ReceiveCommand(...):Integer; var ... lpUSBOverlapped : lpOverlapped; USBOverlapped : TOverlapped; begin lpUSBOverlapped := @USBOverlapped; InitOverlapped(lpUSBOverlapped); bRet := UsbBulkRead(deviceHandle, 0, 0, 0, @USBcb, HEADERSIZE, BytesReceived, lpUSBOverlapped); Ret := WaitForSingleObject(USBOverlapped.hEvent, TIMEOUT_VALUE); if (Ret = 0) and (USBOverlapped.InternalHigh = HEADERSIZE) then begin bRet := UsbBulkRead(deviceHandle, 0, 0, 0, Data, USBcb.nDATA, BytesReceived, lpUSBOverlapped); Ret := WaitForSingleObject(USBOverlapped.hEvent, TIMEOUT_VALUE); end else if Ret = 258 then bRet := CancelIO(USBOverlapped.hEvent); if (Ret = 0) and (USBOverlapped.InternalHigh = USBcb.nDATA) then begin ... end else begin Result := USB_RECEIVE_COMMAND_ERROR; if Ret = 258 then bRet := CancelIO(USBOverlapped.hEvent); end; end; ![]() ![]() Werde mich auf jeden Fall damit auseinander setzen. Vielen Dank für Deine Geduld! |
Re: Zugriffsverletzung bei(Kommunikations)Timeout mit overla
Studier mal meine HID-Komponente. In der JVCL oder
![]() Dort wird ein Daten-Event mit einem Thread implementiert. Ist allerdings trickreich und fast undokumentiert. Bei USB Bulk Reads ist uebrigens eine das performante Lesen wirklich trickreich, da man immer mehrere overlapped Reads ausstehen haben muss. Ich weiss nicht inwieweit die DLL dich da unterstuetzt. |
Re: Zugriffsverletzung bei(Kommunikations)Timeout mit overla
Zwei Fragen habe ich noch:
1. Also, die HID Komponente ist doch sehr komplex und hilft mir nicht wirklich weiter. Nachdem ich mich jetzt in das Thema Threads am einarbeiten bin, würde ich folgenden Ansatz versuchen: Ich verpacke einen Lesevorgang in einen separaten Thread:
Delphi-Quellcode:
Wenn Daten empfangen werden, wird ein Event ausgelöst und der Thread beendet sich. Werden keine Daten empfangen, läuft der Timeout ab und der Thread beendet sich auch. Muss ich in diesem Fall die UsbBulkRead Funktion nicht mehr abbrechen, weil der Thread dann nicht mehr exisitiert? Wäre das so der richtige Ansatz?
bRet := UsbBulkRead(deviceHandle, 0, 0, 0, @USBcb, HEADERSIZE, BytesReceived, lpUSBOverlapped);
Ret := WaitForSingleObject(USBOverlapped.hEvent, TIMEOUT_VALUE); 2. Die Geschichte mit den Rückgabewerten stört mich immer noch. Beispielsweise der Rückgabewert 6 von GetLastError, wie oben erwähnt. Gibt es eine Möglichkeit herauszufinden, was das genau bedeutet? Finde es auch unelegant die Rückgabewert als 'Magic Values', beispielsweise auf 44 zu prüfen, anstatt auf XYZ_ERROR.... Nochmals vielen Dank. |
Re: Zugriffsverletzung bei(Kommunikations)Timeout mit overla
Ich gebe auf. erstens fuehle ich mich gerade mal wieder ziemlich schlecht und zweitens fehlt dir offensichtlich zu viel an Grundlagen.
Kann jemand anders uebernehmen? |
Re: Zugriffsverletzung bei(Kommunikations)Timeout mit overla
Zitat:
Zitat:
Zitat:
Ich bedanke mich schon mal im Voraus :!: |
Re: Zugriffsverletzung bei(Kommunikations)Timeout mit overla
Kann mir da niemand weiterhelfen? Wäre sehr wichtig für mich :|
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz