Einzelnen Beitrag anzeigen

Viktorii

Registriert seit: 19. Jul 2007
358 Beiträge
 
#1

Thread & WaitForSingleObject - Access Violation bei SetE

  Alt 6. Feb 2008, 14:33
Hallo zusammen.

Erstmal muss ich sagen, dass Threads usw. mehr oder weniger Neuland für mich sind. Bin deshalb auch für konstruktive Anmerkungen die evtl. etwas off-topic sind, dankbar.
Ich möchte eine USB Kommunikation zwischen PC und einem Gerät aufbauen. Ein Frame besteht jeweils aus Header und den eigentlichen Daten. Dieses Frame wird in zwei Schritten versendet.
Es wird also erst der Header versendet und im zweiten Schritt die Daten. Die Daten dürfen aber erst versendet werden, wenn der Header von Gerät empfangen wurde. Wenn innerhalb eines Timeouts der Header nicht empfangen wurde, soll das Programm in seinen Ursprungszustand zurückkehren. Dies habe ich versucht mit WaitForSingleObject und SetEvent zu erreichen...
Ich habe die den komplette Vorgang für ein Frame einen neuen Thread gepackt:

Delphi-Quellcode:
type
  TBulkTransferThread = class(TThread)
  private
    ...
    ...
  protected
  public
    constructor create( ...
         ... );
  end;


  TBulkWriteThread = class(TBulkTransferThread)
  protected
    procedure CallbackFktWrite(ErrorCode : Longint;
                 NumberOfBytesTransfered : Longint);
    procedure Execute; override;
  end;

...
...

Bei der Implementierung erzeuge ich mir ein Event. Mit Hilfe von WaitForSingleObject und diesem Event möchte ich das Warten realisieren:


Delphi-Quellcode:
implementation

uses
   SysUtils;

constructor TBulkTransferThread.create( ...
                   ... );
begin
    ...
    ...
    inherited create(False);
end;



procedure TBulkWriteThread.Execute();
var
  bRet : BOOL;
  Ret : Integer;

begin

  WriteFinished := TEvent.Create(nil,true,false,'myEvent');

  WriteFinished.ResetEvent;

  // Header versenden
  bRet := USBWriteAsync(...
         ...
                        @TBulkWriteThread.CallbackFktWrite);

  Ret := WaitForSingleObject(Self.WriteFinished.Handle, TIMEOUT_VALUE);

  if Ret = WAIT_OBJECT_0 then
    Ret := USB_OK
  else
    Ret := USB_SEND_COMMAND_ERROR;

  WriteFinished.ResetEvent;

  if (Ret = USB_OK) and (USBcb.nDATA > 0) then
  // Daten versenden
    bRet := USBWriteAsync(...
                ...
                          @TBulkWriteThread.CallbackFktWrite);

  if (Ret = USB_OK) and (USBcb.nDATA > 0) then
    Ret := WaitForSingleObject(Self.WriteFinished.Handle, TIMEOUT_VALUE);

  WriteFinished.Destroy;

  if Ret = WAIT_OBJECT_0 then
    Integer(Status^) := USB_OK
  else
    Integer(Status^) := USB_SEND_COMMAND_ERROR;
end;

In der Callback-Funktion der Senderoutine, welche ausgeführt wird sobald die Daten versendet wurden, wird das Event gesetzt:

Delphi-Quellcode:
Procedure TBulkWriteThread.CallbackFktWrite(ErrorCode : Longint; NumberOfBytesTransfered : Longint);
begin
  if ErrorCode <> 0 then
  begin
    ErrorCode := GetLastError();
    MessageDlg('Error#: ' + IntToStr(ErrorCode), mtError, [mbOk], 0);
  end;

  SetEvent(Self.WriteFinished.Handle);      // <-- Hier access violation!!


end;

Soweit, so gut. Der Header wird versendet, kommt beim Gerät an und die Callback-Funktion wird aufgerufen.
Allerdings tritt bei SetEvent eine access violation auf:

'In Porjekt ... trat ein Problem mit folgender Meldung auf: 'access violation at 0x0046b567: read of address 0x00000060'. Prozess angehalten'


Ich bekomme nicht heraus, was ich falsch gemacht habe. Wer kann mir da helfen?

Vielen Dank
  Mit Zitat antworten Zitat