Delphi-Quellcode:
// für 32 Bit-Delphi (mal sehn, ob die den StringCheckingScheiß jetzt endlich wieder ausbauen)
const
cDynArrayInfoA = 2 * SizeOf(LongInt);
{$IF CompilerVersion >= 20.0}
cDynArrayInfoS = 3 * SizeOf(LongInt);
{$ELSE}
cDynArrayInfoS = cDynArrayInfoA;
{$IFEND}
type
TDynArrayInfo = packed Record
RefCount: LongInt;
ElementCount: LongInt;
Data: packed Array[0..High(Integer) - cDynArrayInfoA - 1] of Byte;
End;
PDynArrayInfo = ^TDynArrayInfo;
// PInfo := @Var - cDynArrayInfoA;
TAnsiStringInfo = packed Record
{$IF CompilerVersion >= 20.0}
CharSize: Word; // könnte auch sein, daß CharSize und Codepage andersrum liegen
Codepage: Word; // (dieser Schrott stammt von dem blöden StringChecking)
{$IFEND}
RefCount: LongInt;
ElementCount: LongInt;
Data: packed Array[1..High(Integer) - cDynArrayInfoS] of AnsiChar;
End;
PAnsiStringInfo = ^TAnsiStringInfo;
// PInfo := @Var - cDynArrayInfoS;
TUnicodeStringInfo = packed Record
{$IF CompilerVersion >= 20.0}
CharSize: Word;
Codepage: Word;
{$IFEND}
RefCount: LongInt;
ElementCount: LongInt;
Data: packed Array[1..(High(Integer) - cDynArrayInfoS) div 2] of WideChar;
End;
PUnicodeStringInfo = ^TUnicodeStringInfo;
// PInfo := @Var - cDynArrayInfoS;
TDynArrayInfo<TheField> = packed Record
RefCount: LongInt;
ElementCount: LongInt;
Data: packed Array[0..(High(Integer) - cDynArrayInfoA) div SizeOf(TheField) - 1] of TheField;
End;
TStringInfo<TheChar> = packed Record
{$IF CompilerVersion >= 20.0}
CharSize: Word;
Codepage: Word;
{$IFEND}
RefCount: LongInt;
ElementCount: LongInt;
Data: packed Array[1..(High(Integer) - cDynArrayInfoS) div SizeOf(TheChar)] of TheChar;
End;
Der interne Zeiger zeigt jeweils auf .Data
Delphi-Quellcode:
var
MyArray = array of irgendwas;
if MyArray <> nil then
TheLength := PDynArrayInfo(Integer(MyArray) - SDynArrayInfoA).ElementCount
else
TheLength := 0;
PS: Bei den Strings ist jeweils noch ein abschließendes #0 nach den Stringdaten, für die Kompatibilität und eine direkte Konvertierungsmöglichkeit in einen PChar/PAnsiChar/PWideChar.
Es ist also ein DynArray, mit einem zusätzlichen Feld.
Und wenn man sich nun den "alten"
ShortString ansieht,
dann erkennt man, warum Delphi-Strings mit 1 beginnen.
Delphi-Quellcode:
type
TShortStringInfo = packed Record
Len: Byte;
Chars: packed Array[1..255{1..Len}] of Char;
End;
PShortStringInfo = ^TShortStringInfo;
// PInfo := @Var;