Thema: Delphi String-Interna nutzen

Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

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

String-Interna nutzen

  Alt 19. Sep 2010, 22:16
Delphi-Version: 2006
Da in Delphi (leider) Vieles versteckt nicht direkt zugänglich ist,
gibt es hier einen kleinen Converter für alle Strings.

Man kann damit via Cast auf einige interne Daten fast aller delphieigenen Stringtypen zugreifen (abgesehn vom ShortString, aber da dürfte der Cast eh fehltschlagen, und WideString).

Allerdings ist dieses so nur ab Delphi 2006 / Turbo Delphi nutzbar,
aber dafür bietet dieser Record einige Zusatzfeatures, welche das Original System.StrRec, in der System-Unit von Delphi, nicht bietet.
(vorallem den Cast ohne einrechnen eines Offsets ala System.Skew oder System.rOff)

z.B.:
Delphi-Quellcode:
Var S: String; // String, AnsiString oder das neue UnicodeString
MoveMemory(sonstwohin, StrRec(S).Data, StrRec(S).DataSize);
Delphi-Quellcode:
type
  // do not use VStrRec directly
  StrRec = ^VStrRec;
  VStrRec = packed record
  private
    function GetW(Index: Integer): Word; inline;
    procedure SetW(Index: Integer; Value: Word); inline;
    function GetL(Index: Integer): LongInt; inline;
    procedure SetL(Index: Integer; Value: LongInt); inline;
  public
    function Assigned: Boolean; inline;
    {$IF CompilerVersion >= 20.0}
    property CodePage: Word index -12 read GetW write SetW;
    property ElemSize: Word index -10 read GetW {write SetW};
    {$IFEND}
    property RefCount: LongInt index -8 read GetL {write SetL};
    property Length: LongInt index -4 read GetL {write SetL};
    function Data: Pointer; inline;
    function DataSize: Integer; inline;
  end;

function VStrRec.GetW(Index: Integer): Word;
begin
  if @Self <> nil Then
    Result := PWord(PAnsiChar(@Self) + Index)^
  else Result := 0;
end;

procedure VStrRec.SetW(Index: Integer; Value: Word);
begin
  if @Self <> nil Then
    PWord(PAnsiChar(@Self) + Index)^ := Value;
end;

function VStrRec.GetL(Index: Integer): LongInt;
begin
  if @Self <> nil Then
    Result := PLongInt(PAnsiChar(@Self) + Index)^
  else Result := 0;
end;

procedure VStrRec.SetL(Index: Integer; Value: LongInt);
begin
  if @Self <> nil Then
    PLongInt(PAnsiChar(@Self) + Index)^ := Value;
end;

function VStrRec.Assigned: Boolean;
begin
  Result := @Self <> nil;
end;

function VStrRec.Data: Pointer;
begin
  Result := @Self;
end;

function VStrRec.DataSize: Integer;
begin
  Result := Length {$IF CompilerVersion >= 20.0} * ElemSize {$IFEND};
end;
$2B or not $2B

Geändert von himitsu (19. Sep 2010 um 22:20 Uhr)
  Mit Zitat antworten Zitat