Zitat von
Christian Seehase:
Kommt drauf an, was Du als "nicht mehr in dieser Art" ansiehst.
Jetzt ist der Zähler ein Integer, der auf den Postionen String bis String-3 liegt, in negativer Richtung gefolgt von einem, ebenfalls 32 Bit grossen, Referenzzähler.
Genau das meinte ich ja
Delphi-Quellcode:
Const SDynArrayInfoR = 2 * SizeOf(LongInt);
SDynArrayInfo = SizeOf(LongInt) + SDynArrayInfoR;
Type TShortStringInfo = packed Record
Length: Byte;
Chars: packed Array[1..255{or 1..Length}] of Char;
End;
TDynArrayInfo = packed Record
MemoryInfo: LongInt;
RefCount: LongInt;
ElementCount: LongInt;
Data: packed Array[0..0{High(LongInt) - SDynArrayInfo - 1}] of Byte;
End;
TAnsiStringInfo = packed Record
MemoryInfo: LongInt;
RefCount: LongInt;
ElementCount: LongInt;
Data: packed Array[1..High((LongInt) - SDynArrayInfo] of AnsiChar;
End;
TWideStringInfo = packed Record
MemoryInfo: LongInt;
RefCount: LongInt;
ElementCount: LongInt;
Data: packed Array[1..(High((LongInt) - SDynArrayInfo) div 2] of WideChar;
End;
Der Unterschied ist halt, daß es das Längen
Byte(an sich) ja nicht mehr gibt,
außerdem zeigt jetzt der Pointer of Typ auf das 1. Zeichen und nicht mehr auf das LängenByte (wie beim ShortString).
@S beim ShortString zeigt auf TShortStringInfo.Length,
wärend bei den anderen Typen Pointer(S) auf Typ.Data verweist.
Komplett sieht das Ganze dann so bei mir aus:
Delphi-Quellcode:
(***************************************************************************************)
(*** Compiler Intern Data-Types ********************************************************)
(***************************************************************************************)
Type TShortStringInfo =
packed Record // PShortStringInfo := @Var
Length: Byte;
Chars:
packed Array[1..255
{or 1..Length}]
of Char;
End;
PShortStringInfo = ^TShortStringInfo;
(*************************************************************************** )
( )
( P___Info[C] := Pointer(var) - SDynArrayInfo )
( Pointer(var) := T___Info[C].___Addr )
( )
( A String/AnsiString is an Array of Char and just the same as near the )
( Array of Char an additional #0 is attached also there still behind. )
( (for the PChar compatibility) )
( )
( The WideString and the Array of WideChar are also identical )
( and there #0#0 hide themselves behind that. )
( )
(*************************************************************************** )
( )
( T___Info / P___Info: )
( ******************** )
( )
( Pointer(var) = nil > nil {in EXE} > nil {in RAM} )
( )
( MemoryInfo - - <> 0 )
( RefCount - = -1 >= 1 )
( ElementCount - = Length(var) = Length(var) )
( Data - = var = var )
( )
(*************************************************************************** )
( )
( T___InfoC / P___InfoC: )
( ********************** )
( )
( Pointer(var) = nil > nil {in EXE} > nil {in RAM} )
( )
( MemoryInfo = 0 = 0 <> 0 )
( RefCount = 0 = -1 >= 1 )
( ElementCount = 0 >= 1 = Length(var) >= 1 = Length(var) )
( Data - = var = var )
( )
(****************************************************************************)
{ No Type }
{}Const SDynArrayInfoR = 2 * SizeOf(LongInt);
{} SDynArrayInfo = SizeOf(LongInt) + SDynArrayInfoR;
{}Type TDynArrayInfo =
packed Record
{} MemoryInfo: LongInt;
{} RefCount: LongInt;
{} ElementCount: LongInt;
{} Data:
packed Array[0..0
{High(Integer) - SDynArrayInfo - 1}]
of Byte;
{} End;
Type PDynArrayInfo = ^TDynArrayInfo;
TDynArrayInfoC =
packed Record
MemoryInfo: LongInt;
RefCount: LongInt;
ElementCount: LongInt;
DataAddr: Pointer;
isVar: LongBool;
End;
{ No Types }
{}Type TAnsiStringInfo =
packed Record
{} MemoryInfo: LongInt;
{} RefCount: LongInt;
{} ElementCount: LongInt;
{} Data:
packed Array[1..High(Integer) - SDynArrayInfo]
of AnsiChar;
{} End;
{} TWideStringInfo =
packed Record
{} MemoryInfo: LongInt;
{} RefCount: LongInt;
{} ElementCount: LongInt;
{} Data:
packed Array[1..(High(Integer) - SDynArrayInfo)
div 2]
of WideChar;
{} End;
Type PAnsiStringInfo = ^TAnsiStringInfo;
TAnsiStringInfoC =
packed Record
MemoryInfo: LongInt;
RefCount: LongInt;
ElementCount: LongInt;
DataAddr: PAnsiChar;
isVar: LongBool;
End;
PWideStringInfo = ^TWideStringInfo;
TWideStringInfoC =
packed Record
MemoryInfo: LongInt;
RefCount: LongInt;
ElementCount: LongInt;
DataAddr: PWideChar;
isVar: LongBool;
End;
Function DynArrayInfo (
Const A): PDynArrayInfo;
Function DynArrayInfoC(
Const A): TDynArrayInfoC;
Function StringInfo (
Const S: AnsiString): PAnsiStringInfo;
Overload;
Function StringInfoC(
Const S: AnsiString): TAnsiStringInfoC;
Overload;
{$IFNDEF UseOLEWideString}
Function StringInfo (
Const S: WideString): PWideStringInfo;
Overload;
Function StringInfoC(
Const S: WideString): TWideStringInfoC;
Overload;
{$ENDIF}
Achtung: Die Typen für WideStrings bitte nicht ganz so ernst nehmen, denn aus unerfindlichen Gründen ist die aktuell implementierte Version der WideStrings nicht von Borland definiert worden - es wird einfach ein OLEWideString verwendet, welcher etwas anders aufgebaut ist.
Dieses ist auch der Hauptgrund, weßhalb WideStrings nicht über eine Referenzzählung verfügen.