![]() |
TComport - Access Violation beim wieder-öffnen
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:
Theoretisch könnte dieser Quelltext ursächlich sein, ich meine, es habe mal in TData.Clear geknallt, aber ich sehe darin keinen Fehler!?
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; Wo stimmt da was nicht? Danke im Voraus fürs mitdenken. |
AW: TComport - Access Violation beim wieder-öffnen
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; |
AW: TComport - Access Violation beim wieder-öffnen
Inc(P); ??
|
AW: TComport - Access Violation beim wieder-öffnen
Zitat:
Wenn ich es weglasse, bleibe ich auf der Stelle stehen und bekomme immer das selbe Zeichen. Oder wie meinst du das? Zitat:
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 :pale: |
AW: TComport - Access Violation beim wieder-öffnen
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? |
AW: TComport - Access Violation beim wieder-öffnen
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. |
AW: TComport - Access Violation beim wieder-öffnen
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.
|
AW: TComport - Access Violation beim wieder-öffnen
Zitat:
Danke samso :cheers: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:19 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