AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi TComport - Access Violation beim wieder-öffnen
Thema durchsuchen
Ansicht
Themen-Optionen

TComport - Access Violation beim wieder-öffnen

Ein Thema von SearchBot · begonnen am 16. Nov 2016 · letzter Beitrag vom 3. Dez 2016
Antwort Antwort
SearchBot

Registriert seit: 27. Jun 2004
Ort: N-W vom Bodensee
317 Beiträge
 
Delphi 12 Athens
 
#1

TComport - Access Violation beim wieder-öffnen

  Alt 16. Nov 2016, 15:06
Hallo

ich verwende die TComport-Komponente 4.11

Ich habe das Problem, daß es spätestens bei Programmende zu dieser Meldung kommt und abschließend mit dem Fensterchen "Runtime Error 216":
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt ***.exe ist eine Exception der Klasse $C0000005 mit der Meldung 'access violation at 0x0040a3bc: read of address 0x00000058' aufgetreten.
---------------------------

"Anhalten" bringt mich in ein für mich nichts sagendes CPU-Fenster, der Stack-Verlauf führt mich nicht in den Quelltext.

Dieses Verhalten habe ich immer dann, wenn ich Daten gelesen habe (RxBuf, siehe unten), den Comport schließe und danach wieder öffne - oder spätestens eben bei Programmende.

Es scheint auch keine Exception zu sein, die in der Komponente abgefangen werden kann (onException wird nicht angesprungen).

Vielleicht habe ich auch was in meinem Object (hier ein Auszug) falsch gemacht?!

Delphi-Quellcode:
  type TData = object
    Bytes: array[1..50] of byte;
    Len:byte;
    procedure Clear;
  end;


type ... // in einem Object
  private
   fReceived:AnsiString;
   procedure CleanReceived(const Value:Ansistring);
  public

   Data:TData;
   property received:AnsiString read fReceived write CleanReceived;
end;

procedure TData.Clear;
var I: Integer;
begin
  for I := 1 to 50 do begin
   Bytes[i]:=0;
   len:=0;
  end;
end;

procedure .. .CleanReceived(const Value:AnsiString);
begin
  setlength(fReceived,Length(Value));
  fReceived:=Value;
end;

procedure TForm1.ComPort1RxBuf(Sender: TObject; const Buffer; Count: Integer);
var
  I: Integer; Buf:Array[1..100] of AnsiChar; s:AnsiString; P:PansiChar;
begin
  setLength(s,count);

  p:=pAnsichar(@Buffer);
  for I := 1 to Count do begin
    if i<=100 then begin
     Buf[i]:=p^;
     Data.Bytes[i]:=ord(Buf[i]);
    end;
    inc(p);
  end;
  if count<=100 then
  s:=copy(Buf,1,count)
  else
  s:=copy(Buf,1,100);

  received:=s; //pur wie es kommt ins property

  s:=AsciiToHex(S); //verschönern als lesefreundliche Hex-Ausgabe; aus JvCsvParse

  for I := 1 to length(s)*2 do
   if I mod 3=0 then insert(#32,s,i);

  if count>100 then s:=s+'...';

  lb_Answer.Caption:=s;
end;
Theoretisch könnte dieser Quelltext ursächlich sein, ich meine, es habe mal in TData.Clear geknallt, aber ich sehe darin keinen Fehler!?

Wo stimmt da was nicht?
Danke im Voraus fürs mitdenken.

Geändert von SearchBot (16. Nov 2016 um 15:09 Uhr)
  Mit Zitat antworten Zitat
Neumann

Registriert seit: 6. Feb 2006
Ort: Moers
536 Beiträge
 
Delphi 12 Athens
 
#2

AW: TComport - Access Violation beim wieder-öffnen

  Alt 16. Nov 2016, 20:14
Warum nicht einfach den Event OnRXChar und dann die Funktion Readstr nehmen? Dann kann man sich die ganze die Sache extrem vereinfachen.
Das einzige Problem ist, dass OnRXChar mehrfach feuert, wenn Daten kommen. Man muss also einen Puffer (string) z.B. als Formvariable mit den Teilstücken befüllen. Wenn das Endzeichen oder die Länge der Sendung bekannt ist, ist es auch kein Problem zu erkennen wann die Sendung fertig eingelesen ist;
Ralf
Gruß vom Niederrhein
  Mit Zitat antworten Zitat
EmWieMichael

Registriert seit: 28. Mär 2012
103 Beiträge
 
#3

AW: TComport - Access Violation beim wieder-öffnen

  Alt 17. Nov 2016, 07:55
Inc(P); ??
  Mit Zitat antworten Zitat
SearchBot

Registriert seit: 27. Jun 2004
Ort: N-W vom Bodensee
317 Beiträge
 
Delphi 12 Athens
 
#4

AW: TComport - Access Violation beim wieder-öffnen

  Alt 17. Nov 2016, 10:37
Weil ich zeichenweise den Inhalt aus dem typenlosen Buffer nach Buf-Array kopiere.
Wenn ich es weglasse, bleibe ich auf der Stelle stehen und bekomme immer das selbe Zeichen.

Oder wie meinst du das?

Warum nicht einfach den Event OnRXChar und dann die Funktion Readstr nehmen? Dann kann man sich die ganze die Sache extrem vereinfachen.
Das einzige Problem ist, dass OnRXChar mehrfach feuert, wenn Daten kommen. Man muss also einen Puffer (string) z.B. als Formvariable mit den Teilstücken befüllen. Wenn das Endzeichen oder die Länge der Sendung bekannt ist, ist es auch kein Problem zu erkennen wann die Sendung fertig eingelesen ist;
Die Bytes, die eintreffen, haben kein spezielles Endzeichen.
Das Ende der Übermittlung ist ein CRC aus den zuvor eingetroffenen bytes.
Es kann aber auch sein, daß der Controller, der die Bytes sendet, spinnt und endlos unsinnige Daten liefert (dann muss man ihn stromlos setzen, um das zu beenden).


Was ich nicht verstehe ist (auch), wenn ich den Comport schließe, dann wird ja die "Datei" geschlossen, es werden auch Threads beendet und alles ist erstmal gut. Wenn ich den Comport wieder öffne, bekomme ich die Zugriffsverletzung, aber nur wenn ich zuvor Daten empfangen habe.
Kann es also sein, daß vom vorherigen Mal noch Daten herumgeistern und es deshalb knallt (wobei ich den Ort nicht finden kann)?

Die Komponente funktioniert an sich prima, bestimmt habe ich irgendwo Mist gebaut, aber ich finde es nicht
  Mit Zitat antworten Zitat
Neumann

Registriert seit: 6. Feb 2006
Ort: Moers
536 Beiträge
 
Delphi 12 Athens
 
#5

AW: TComport - Access Violation beim wieder-öffnen

  Alt 17. Nov 2016, 10:59
Man muss den Comport nicht schließen. Es ist durchaus ok, beim Programmstart zu öffnen und beim Programmende zu schließen. Hat man Geräte, die 'ungefragt' senden geht das gar nicht anders.

Was für ein Gerät sendet da?
Ralf
Gruß vom Niederrhein
  Mit Zitat antworten Zitat
SearchBot

Registriert seit: 27. Jun 2004
Ort: N-W vom Bodensee
317 Beiträge
 
Delphi 12 Athens
 
#6

AW: TComport - Access Violation beim wieder-öffnen

  Alt 28. Nov 2016, 15:49
Ja, im Grunde mache ich das auch so: beim Start öffnen und am Ende schließen - und eben da wird dann mit der Zugriffsverletzung geworfen, oder eben dann, wenn ich den Port wieder öffne, nachdem ich ihn geschlossen habe.

Der Sender ist ein kleiner Mikrocontroller, der 4-6 Befehle kann. Sehr mikro eben.
  Mit Zitat antworten Zitat
samso

Registriert seit: 29. Mär 2009
439 Beiträge
 
#7

AW: TComport - Access Violation beim wieder-öffnen

  Alt 29. Nov 2016, 12:14
Die Länge von data.bytes ist nur 50, während die Länge von buf 100 ist. Das illegale Überschreiben von Speicher wird auch durch die Abfrage "if i<=100" nicht verhindert.
  Mit Zitat antworten Zitat
SearchBot

Registriert seit: 27. Jun 2004
Ort: N-W vom Bodensee
317 Beiträge
 
Delphi 12 Athens
 
#8

AW: TComport - Access Violation beim wieder-öffnen

  Alt 3. Dez 2016, 11:44
Die Länge von data.bytes ist nur 50, während die Länge von buf 100 ist. Das illegale Überschreiben von Speicher wird auch durch die Abfrage "if i<=100" nicht verhindert.
Verrückt, aber der Fehler ist verschwunden!
Danke samso
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz