![]() |
Delphi-Version: XE5
RTTI-Bugs?
Moin,
kennt jemand weitere Fehler in der RTTI?
Vorallm der erste Punkt ist ein großes Problem, denn dort sind wirklich die grundlegenden RTTI-Rohdaten das Problem. Außerdem wird ein Set, vorallem in der neuen RTTI, als "ordinaler" Typ behandelt, zusammen mit Enums, Integer und Chars, und das geht nunmal nur bis 8 Byte gut. Die neue RTTI geht über TTypeData.OrdType, für die Größenbestimmung und da sind bei mehr als 8 Byte falsche/ungültige Werte enthalten. Ein QC kommt demnächst. (erstmal sehn was sich noch für Fehler anfinden) Meine Test-Daten, für den ersten Punkt:
Delphi-Quellcode:
Und das, was man aus der RTTI auslesen kann: (als //-Kommentare sind die richtigen Werte enthalten, bzw. eine Erklärung)
type
TMyEnum1 = 0..5; // 1 ... 8-1 TMySet1 = set of TMyEnum1; // 1 Byte TMyEnum2 = 0..15; // 8 ... 16-1 TMySet2 = set of TMyEnum2; // 2 Byte TMyEnum4 = 0..30; // 16 ... 32-1 TMySet4 = set of TMyEnum4; // 4 Byte TMyEnum8 = 0..33; // 32 ... 64-1 TMySet8 = set of TMyEnum8; // 8 Byte TMyEnum20 = 0..155; // ... 160-1 TMySet20 = set of TMyEnum20; // 20 Byte TMyEnum32 = 0..250; // ... 256-1 TMySet32 = set of TMyEnum32; // 32 Byte (multiple of 4) TMyEnum_1 = 0..$70; TMyEnum_2 = 0..$7F00; TMyEnum_4 = 0..$7FFF0000; TMyEnum_4u = 0..$FFFF0000; TMyClass = class abstract FField: Integer; FMyField1: TMySet1; FMyField2: TMySet2; FMyField4: TMySet4; FMyField8: TMySet8; FMyField32: TMySet32; FMyField_1: TMyEnum_1; FMyField_2: TMyEnum_2; FMyField_4: TMyEnum_4; FMyField_4u: TMyEnum_4u; function Getter(A, B: string; Index: Integer): TMySet4; virtual; abstract; procedure Setter(A, B: string; Index: Integer; Value: TMySet4); virtual; abstract; property X[A, B: string]: TMySet4 index 3 read Getter write Setter; published property I1: Integer index 1 read FField write FField default 3; property I2: Integer index 2 read FField write FField stored False ; property I3: Integer index 3 read FField write FField stored False default 3; end;
Delphi-Quellcode:
// MinValue..MaxValue {TypeSize ClassName}
TMyEnum1 = {Integer}0..5; {Size=1 TRttiOrdinalType} TMySet1 = set of TMyEnum1; {Size=1 OrdType=1=otUByte TRttiSetType} TMyEnum2 = {Integer}0..15; {Size=1 TRttiOrdinalType} TMySet2 = set of TMyEnum2; {Size=2 OrdType=3=otUWord TRttiSetType} TMyEnum4 = {Integer}0..30; {Size=1 TRttiOrdinalType} TMySet4 = set of TMyEnum4; {Size=4 OrdType=5=otULong TRttiSetType} TMyEnum8 = {Integer}0..33; {Size=1 TRttiOrdinalType} TMySet8 = set of TMyEnum8; {Size=1343671120 OrdType=255 TRttiSetType} // SizeOf() = 8 // OrdType = invalid TMyEnum20 = {Integer}0..155; {Size=1 TRttiOrdinalType} TMySet20 = set of TMyEnum20; {Size=1 OrdType=1 TRttiSetType} // SizeOf() = 20 // OrdType = invalid TMyEnum32 = {Integer}0..250; {Size=1 TRttiOrdinalType} TMySet32 = set of TMyEnum32; {Size=1 OrdType=1 TRttiSetType} // SizeOf() = 32 // OrdType = invalid TMyEnum_1 = {Integer}0..112; {Size=1 TRttiOrdinalType} TMyEnum_2 = {Integer}0..32512; {Size=2 TRttiOrdinalType} TMyEnum_4 = {Integer}0..2147418112; {Size=4 TRttiOrdinalType} TMyEnum_4u = {Cardinal}0..-65536; {Size=4 TRttiOrdinalType} // if MinValue > MaxValue then Cardinal TMyClass = class {Package1.bpl Unit14.TMyClass Instance Size=4 TRttiInstanceType} public FField: Integer; FMyField1: TMySet1; FMyField2: TMySet2; FMyField4: TMySet4; FMyField8: TMySet8; FMyField32: TMySet32; FMyField_1: TMyEnum_1; FMyField_2: TMyEnum_2; FMyField_4: TMyEnum_4; FMyField_4u: TMyEnum_4u; function Getter(A: string; B: string; Index: Integer): TMySet4; virtual; {Index=0 Addr=$237B23D8} procedure Setter(A: string; B: string; Index: Integer; Value: TMySet4); virtual; {Index=1 Addr=$237B23E0} property X[A: string; B: string; Index: Integer]: TMySet4 read _Getter write _Setter; // TRttiIndexedProperty.ToString liefert für "X" nur eine "Zugriffsverletzung bei Adresse 6F687465. Lesen von Adresse 6F687465" // es sollte eigentlich "property X[A: string; B: string; Index: Integer]: TMySet4" liefern, was aber nicht am Set liegt published // für die Namen der Setter/Getter hab ich noch keine Übersetztung eingeaut property I1: Integer index 1 read _Field0004 write _Field0004 default 3; property I2: Integer index 2 read _Field0004 write _Field0004; property I3: Integer index 3 read _Field0004 write _Field0004 default 3; end; |
AW: RTTI-Bugs?
Was mir seit langem übel aufstößt ist fehlende komplette RTTI für Records und dort insbesondere die "alten" strings.
|
AW: RTTI-Bugs?
In der alten RTTI?
Published-Felder sollten aber dennoch vorhanden sein. :gruebel: (published gibt es im Record nicht) In der neuen "erweiterten RTTI" sind die eigentlich vorhaden. (siehe der Anhang in ![]() [add]
Delphi-Quellcode:
Und über die RTTI generiert:
type
TMyRecord = record A: Byte; B: Integer; C: ShortString; D: string[3]; E: string; property F: Integer read B; procedure G; end;
Delphi-Quellcode:
Warum gerade der eine ShortString mit Längenangabe nicht geht, müsste ich nochmal prüfen. (mir war so, als gingen die)
TMyRecord = record {Package1.bpl Unit14.TMyRecord Managed Record Size=272 TRttiRecordType}
public { 0} A: Byte; { 4} B: Integer; { 8} C: ShortString; {264} D: {unknown}; {268} E: string; procedure G; {Addr=$26B37698} end; [add2] OK, das Problem besteht erstmal nur bei eingebettenten Strings.
Delphi-Quellcode:
type
TMyStr = string[3]; TMyRecord = record A: Byte; B: Integer; C: ShortString; D: TMyStr; E: string; property F: Integer read B; procedure G; end;
Delphi-Quellcode:
Dabei fällt mir ein, daß es auch ein Problem mit Sets gab.
TMyStr = string[3]; {Package1.bpl Unit14.TMyStr Size=4 TRttiStringType}
TMyRecord = record {Package1.bpl Unit14.TMyRecord Managed Record Size=272 TRttiRecordType} public { 0} A: Byte; { 4} B: Integer; { 8} C: ShortString; {264} D: TMyStr; {268} E: string; procedure G; {Addr=$23AC7684} end;
Delphi-Quellcode:
geht, aber bei
set of TEnum
Delphi-Quellcode:
knallt es oftmals.
set of (one, two, tree);
|
AW: RTTI-Bugs?
Nur damit die Begrifflichkeiten nicht irreführen:
Es gibt keine alte und neue RTTI, es gibt nur eine RTTI. Das Zeugs in der Rtti.pas greift nach wie vor auf die Strukturen in der TypInfo.pas zu. Was neu ist, ist, dass die vom Compiler generierten Informationen erweitert wurden (in Bezug auf nicht published Member, Attribute etc). Aber auch die könnte man, wenn man mutig genug ist, nur mit der TypInfo.pas auslesen. Außerdem kannst du dir mind einen QC Eintrag sparen, denn die indexed Property wird unter XE6 korrekt ausgegeben. |
AW: RTTI-Bugs?
Die Struktur der RTTI wurde erweitert und es stehen jetzt standardmäßig zu mehr Dingen Daten darin, welche es früher nicht gab, wie z.B. private Felder.
Viele der neuen Infos werden von den TRtti-Klassen direkt aus den Record-Strukturen gelesen, ohne daß es da neue Ausleseprozeduren in der TypInfo dafür gibt. Und es gibt die neuen OOP-mäßige Klassenstruktur, zum Auflisten der Daten. Mindestens 3 Exceptions gab es in XE6 auch noch, beim Auflisten der kompletten RTTI eines gewissen Programmes, aber ich weiß jetzt auf die Schnelle nicht, welche das waren. (zumindestens waren es weniger, als im XE3) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:46 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz