AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Length zerstört AnsiString

Ein Thema von OlafSt · begonnen am 15. Sep 2009 · letzter Beitrag vom 15. Sep 2009
Antwort Antwort
OlafSt

Registriert seit: 2. Mär 2007
Ort: Hamburg
284 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

Length zerstört AnsiString

  Alt 15. Sep 2009, 16:41
Folgende Klasse ist definiert:

Delphi-Quellcode:
type
  TFlexTransportSDS = class(TObject)
  strict private
     FTargetSSI: integer;
     FMessage: AnsiString; //Nix Unicode
     FHandle: integer;
     FIsStatus: Boolean;
     FStatus: Word;
  protected
  public
     //Die anderen Konstruktoren habe ich hier auskommentiert, sie spielen keine Rolle
     constructor Create(ATargetSSI: integer; const AMessage: AnsiString; AHandle: integer); //overload;
     //constructor Create(ATargetSSI: integer; AStatusValue: integer); overload;
     //constructor Create; overload;

     property TargetSSI: integer read FTargetSSI write FTargetSSI;
     property TheMessage: AnsiString read FMessage write FMessage;
     property SDSHandle: integer read FHandle write FHandle;
     property IsStatus: boolean read FIsStatus write FIsStatus;
     property StatusValue: Word read FStatus write FStatus;
  end;
Der Konstruktor sieht wie folgt aus:
Delphi-Quellcode:
constructor TFlexTransportSDS.Create(ATargetSSI: integer; const AMessage: AnsiString; AHandle: integer);
var
   i: integer;
begin
     FTargetSSI:=ATargetSSI;

     //Originalcode
     //FMessage:=AMessage;
     //funktioniert ebenfalls nicht

     for i := 1 to Length(AMessage) do
         FMessage:=FMessage+AMessage[i];
     FHandle:=AHandle;
end;
Nun erzeugen wir eine Instanz dieses neuen Objekts:

Delphi-Quellcode:
var
   TF: TFLexTransportSDS;
   s: AnsiString;
begin
     s:=#3#0'$PSCOCM,21';
     TF:=TFlexTransportSDS.Create(104, s, 114);
end;
Debuggen wir nun durch den Konstruktor hindurch, wird AMessage zerfetzt, es bleibt "#3?????" und eine Menge Nullbytes davon übrig.
Ich hab das ganze dann mit dem Disassember verfolgt und sehe, das Length nur noch mit Unicode-Strings arbeiten kann, ergo erzeugt der Compiler einen Aufruf nach @InternalLStrToUStr, um aus AMessage erstmal Unicode zu machen und dann die Länge zu ermitteln.
Offensichtlich ist @InternalLStrToUStr mit einem Problem behaftet: Das erste Zeichen (#3) wird noch erkannt, die folgende #0 aber nicht mehr und die Routine flippt aus Mein Originalstring (AMessage !!) ist anschließend zerstört.

Kann das wer nachvollziehen ?
Gibt es eine Möglichkeit, Length zu umgehen (StrLen geht wegen des Nullbytes NICHT !) ?

Wenn dies ein tatsächlicher Fehler in Delphi ist, verschrotte ich D2009 - wer weiß, was noch für Granaten da schlummern.

Compiler ist Delphi 2009 Professional, Update 3 plus Update 4 (Database Pack Update) plus Help Update 3 sind installiert.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.619 Beiträge
 
Delphi 12 Athens
 
#2

Re: Length zerstört AnsiString

  Alt 15. Sep 2009, 16:46
Das "Zerstören" kann ich unter Delphi 2007 wohl nicht nachvollziehen, aber auch ein AnsiString hört beim #0 auf. Wäre Shortstring eine Option?
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.195 Beiträge
 
Delphi 10.4 Sydney
 
#3

Re: Length zerstört AnsiString

  Alt 15. Sep 2009, 16:55
Verwendung von #0 als Teil eines Strings ist eine ganz schlechte Idee. Unter C/C++ würdest du damit keine 3 Quellcodezeilen weit kommen. Falls es sich um ein Transportprotokoll handelt würde ich hier eher mit Streams arbeiten. Du kannst von Glück reden das dein Code bei alten Delphi-Versionen halbwegs funktioniert hat.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#4

Re: Length zerstört AnsiString

  Alt 15. Sep 2009, 17:06
Ich hatte mal ein ähnliches Problem mit Sonderzeichen, war ziemlich schwer aufzuspüren, weil die Fehler ganz woanders (und nicht immer an der gleichen Stelle) auftraten. Hach, das war eine herrliche Debugging-Session...

Probier mal statt #0 chr(0) zu schreiben (gilt für die anderen Sonderzeichen auch).
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#5

Re: Length zerstört AnsiString

  Alt 15. Sep 2009, 17:15
Mal so aus der Hüfte gedacht:
wie wäre es mit einem array of char?

das ist kompatibel zu "string" aber die interpretation des Inhalts (#0) fällt weg?

Gruß
K-H
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.033 Beiträge
 
Delphi 12 Athens
 
#6

Re: Length zerstört AnsiString

  Alt 15. Sep 2009, 17:30
Der obere Code sollte funktionieren, da hier zufällig keine "Funktionen" verwendet werden, welche die #0 nicht mögen.

String-Konstante mit #0 ist möglich
Concat (String := String + String) ist möglich
'ne einfache Zuweisung (String := String) ist möglich
und Übergabe als Parameter geht auch

Der Delphi-String benutzt ein LängenenByte (Integer) und ließt nicht die länge anhand einer abschließenden #0 aus ... es gibt aber leider viele Funktionen, welche nach dem C-Standard als PChar arbeiten und auch die oft genutzen WinAPIs arbeiten so C-mäßig.

Also wenn man weiß, was man tut, kann man in einem String alle möglichen Steuerzeichen (auch #0) verwenden.
(mach ich sehr gern, da ich so das automatische Aufräumen mit ausnutzen kann )


Das Problem ist hier vermutlich DELPHI und seine kranke Unicode-Unterstützung und wegen der #0 an 2. Stelle denkt es wäre ein UnicodeString.

Schalte das String-Checking ab und gut ist, außerdem wird dadurch das Programm etwas schneller/schlanker.

http://www.delphipraxis.net/internal...076095#1076095
http://www.delphipraxis.net/internal...075246#1075246


     FMessage: AnsiString; //Nix Unicode das interessiert Delphi2009/2010 nicht, prüft es ständig nach und ändert es dann einfach
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von implementation
implementation

Registriert seit: 5. Mai 2008
940 Beiträge
 
FreePascal / Lazarus
 
#7

Re: Length zerstört AnsiString

  Alt 15. Sep 2009, 19:00
Zitat von himitsu:
Der Delphi-String benutzt ein LängenenByte (Integer) und ließt nicht die länge anhand einer abschließenden #0 aus ... es gibt aber leider viele Funktionen, welche nach dem C-Standard als PChar arbeiten und auch die oft genutzen WinAPIs arbeiten so C-mäßig.
Das war mal so - bevor auch in Delphi die nullterminierten "langen Strings" eingeführt wurden.
Um das Phänomen zu umgehen, kannst du einen ShortString verwenden, der benutzt tatsächlich noch das erste Byte als Längenangabe.
Marvin
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.033 Beiträge
 
Delphi 12 Athens
 
#8

Re: Length zerstört AnsiString

  Alt 15. Sep 2009, 19:06
nicht ganz ... der AnsiString und UnicodeString (seit D2009) haben intern 2 Zusätzliche Integer

- Längenangabe
- Referenzzählung

und, damit man es schön einfach als PChar verwenden kann, eine #0 hintendran,
aber von der Stringverwaltung wird nur die Längenangabe verwendet.

Allerdings gibt es halt Delphifunktionen, welche c-typisch nur auf #0 reagieren,
oder wie z.B. StringReplace, welche zwar selber die Längenangabe auswertet, aber durch Verwendung von Delphi-Referenz durchsuchenAnsiPos dann doch nicht richtig arbeitet
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  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 07:58 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