Zitat:
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.
Achsooooo.... LP steht für long pointer.
Naja, wenn da lp anstatt LP gestanden hätte, wäre ich vielleicht sogar selber drauf gekommen.
Zitat:
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.
Ansonsten funktioniert mittlerweile die 'unelegantere' Lösung ohne einen neuen Thread fast. Da ich mit Thread Programmierung bis jetzt noch nicht wirklich in Berührung gekommen bin, möchte ich das Problem erstmal so lösen, bevor ich mich mit Threads wirklich auseinander setze.
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:
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;
Kann mir jemand Literatur zu Grundlagen für Thread- und
API-Programmierung empfehlen? Habe bis jetzt das hier gefunden:
http://www.michael-puff.de/Developer...mit_Delphi.pdf
http://www.michael-puff.de/Developer...orials_pdf.pdf
Werde mich auf jeden Fall damit auseinander setzen.
Vielen Dank für Deine Geduld!