Einzelnen Beitrag anzeigen

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, 15: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