![]() |
TComPort: Zugriffsverletzung beim Senden eines Strings
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo!
Ich nutze schon länger dieses Forum als Datenbank für Tipps und Codeschnipsel und es hat mir schon oftmals geholfen. Doch nun bin ich einmal mehr mit meinem Latein am Ende und finde keine Lösung dazu. Jetzt hoffe ich auf eure Hilfe. Es geht um ein kleines Programm, welches einen digitalen Druckkalibrator (quasi eine Luftpumpe mit hochgenauem Drucksensor) fernsteuert. Es sind nicht viele Funktionen dazu notwendig. Es werden lediglich Befehle für "Sollwert setzen", "Auf Sollwert pumpen" und "Entlüften" über die Serielle Schnittstelle gesendet. Bis auf "Sollwert setzen" sind die Befehle statisch und für die Kommunikation nutze ich die TComPort von Dejan Crnila, wenn auch nicht die neuste Version, aber sie funktioniert. Die statischen Befehle lassen sich ohne Probleme senden, lediglich bei dem Befehl zum Setzen des Solldrucks, bei dem der Inhalt eines Textfeldes (String zu Integer, mit 10 multiplizieren und wieder zurück zum String) in den zu sendenden String mit eingebaut werden muss, stürzt das Programm nach dem 2. 0der 3. Senden des Befehles mit einer Zugriffsverletzung ab. Statischer Befehl:
Delphi-Quellcode:
Der Befehl zum Senden des Solldruckes:
if ComPort.Connected then begin
Str := ':ps 0 ' + #13; ComPort.WriteStr(Str); Status.Panels[0].Text := Str; end;
Delphi-Quellcode:
EditSW ist ein JvValidateEdit, das einen Double ausgibt. Die komplette Umwandlung und Umrechnung scheint problemlos von Statten zu gehen. Wenn ich ComPort.WriteStr() in diesem Code auskommentiere, so wird der Befehl korrekt in der Statusleiste beliebig oft angezeigt. Nach dem Verbinden mit dem COM (Sende-Befehl nicht auskommentiert), lässt sich der Befehl beim ersten Mal korrekt senden, wobei bereits in der Statusanzeige, welche noch vor dem Senden geändert wird, nur ":pr" steht, anstatt wie gewöhnlich ":pr 0". Im Terminal (0-Modemkabel zwischen 2 COMs) wird der Befehl korrekt angezeigt. Nach dem 2. Senden (Ebenfalls korrekt im Terminal) erscheint die folgende Fehlermeldung, ohne Ausführen über die IDE schließt das Programm einfach:
if ComPort.Connected then begin
TempVal := StrToFloat(EditSW.Value)*10; TxStr := ':pr ' + FloatToStr(TempVal) + #13; Status.Panels[0].Text := TxStr; // Debugging-Infos ausgeben ComPort.WriteStr(TxStr); Anhang 35472 Durch Auskommentieren und Ausprobieren habe ich mittlerweile herausgefunden, dass SendStr vom TComPort ein Problem mit zusammengesetzten Strings hat. Beispiel:
Delphi-Quellcode:
Ich nutze Delphi 6 und TComPort 3.0.
// Funktioniert:
Str := ':ps ' + '0' + #13; ComPort.WriteStr(Str); //Funktioniert nicht und stürzt mit einer Access Violation ab: Str2 := '0'; Str := ':ps 0' + Str2 + #13; ComPort.WriteStr(Str); Kann jemand den Fehler nachvollziehen oder reproduzieren? Vielen Dank für eure Hilfe im Vorraus! Grüße, Sebastian Edit: Wenn ich TxString mit Copy() in einen anderen String kopiere, lässt sich eben jener String problemlos senden. |
AW: TComPort: Zugriffsverletzung beim Senden eines Strings
Also, durch das Kopieren des zu sendenden Strings mittels Copy() in einen neuen String konnte ich auf meinem Rechner das Programm zum laufen bekommen. Auf einem anderen Rechner jedoch tritt der Fehler erneut auf.
|
AW: TComPort: Zugriffsverletzung beim Senden eines Strings
Ich glaube nicht, das Du das Problem korrekt eingekreist hast. Es mag sein, das der Austausch (oder Weglassen) der Stringkonkatenation den Fehler provoziert oder unterdrückt, aber das das SendStr in beiden Fällen identisch aufgerufen wird, liegt der Fehler woanders.
|
AW: TComPort: Zugriffsverletzung beim Senden eines Strings
:thumb:
|
AW: TComPort: Zugriffsverletzung beim Senden eines Strings
Das ist es ja, was mich verwirrt, ich rufe das WriteStr absolut identisch auf, aber bei einem aus 2 Strings zusammengesetzten String tritt der Fehler auf, allerdings kann ich keine weitere Ursache oder eine andere Eingrenzung dafür finden.
|
AW: TComPort: Zugriffsverletzung beim Senden eines Strings
Delphi-Quellcode:
1: Der Compiler ist so schlau und macht aus den drei Stringkonstanten eine Stringkonstante ... zur Laufzeit wird da nichts mehr gemacht, also bleibt das, von der Speicherverwalung her, eine Konstande
// 1
Str := ':ps ' + '0' + #13; // 2 Str2 := '0'; Str := ':ps 0' + Str2 + #13; 2: Da werden Strings verbunden, also entsteht eine eine neue Variable. Das Write schrottet jetzt irgendwie den Speicher, was bei der Konstante wohl keine großen Auswirkungen zeigt, da bei Freigabe des Variablenzeigers kein Eingriff des Speichermanagements eintritt. Aber bei der Variable wird das Speichermanagement so geschrottet, daß es danach in einem Fehler endet. |
AW: TComPort: Zugriffsverletzung beim Senden eines Strings
So sieht der Code im aktuellen TComport aus.
Delphi-Quellcode:
Bringt uns das weiter?
// perform asynchronous write operation
function TCustomComPort.WriteStrAsync(const Str: string; var AsyncPtr: PAsync): Integer; var sa : Ansistring; begin if Length(Str) > 0 then begin sa := AnsiString(str); Result := WriteAsync(Sa[1], Length(Str), AsyncPtr) end else Result := 0; end; // perform synchronous write operation function TCustomComPort.WriteStr(const Str: string): Integer; var AsyncPtr: PAsync; begin InitAsync(AsyncPtr); try WriteStrAsync(Str, AsyncPtr); Result := WaitForAsync(AsyncPtr); finally DoneAsync(AsyncPtr); end; end; |
AW: TComPort: Zugriffsverletzung beim Senden eines Strings
Zitat:
Zitat:
Ist es vllt dieser kleine Unterschied? |
AW: TComPort: Zugriffsverletzung beim Senden eines Strings
@ConnorMcLeod:
Falls Du damit meinst, dass es einmal eine Null und dann zwei Nullen sind: Das ist ein kleiner Flüchtigkeitsfehler meinerseits. Obs nun 1 oder 2 Nullen werden spielt für die (Nicht-)Funktion keine Rolle. Es diente lediglich der Veranschaulichung, welche Kombination funktioniert und welche nicht. |
AW: TComPort: Zugriffsverletzung beim Senden eines Strings
Ja, habe ich gemeint; könnte ja sein, dass Datenbits/Stopbits so eingestellt sind, dass es ein Thema wird.
Ich verwende D2010, TComPort v.4 und com0com für dieses Beispiel und es funkt problemlos:
Delphi-Quellcode:
Schau doch mal mit einem Breakpoint auf ComPort.WriteStr und [F7], wo und warum es kracht.
var
ComPort: TComPort; Str, Str2: string; begin ComPort := TComPort.Create(Self); try Str2 := '0'; Str := ':ps 0' + Str2 + #13; ComPort.Port := 'CNCA0'; ComPort.Open; ComPort.WriteStr(Str); finally FreeAndNil(ComPort); end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:13 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