| Autor |
Beitrag |
baka0815
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Di 06.07.10 12:03
Hallo zusammen,
ich möchte alle published-Eigenschaften eines Objekts herausfinden. Der folgende Code funktioniert allerdings nicht, weil der ClassInfo-Pointer nil ist. Wenn ich statt des markierten Codes die Zeile darüber verwende, funktioniert es problemlos.
Woran liegt das? Das Objekt das ich übergebe ist von TInterfacedObject abgeleitet und implementiert ein Interface. Aber auch wenn ich TObject.Create übergebe ist ClassInfo nil.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| function GetProperties(Obj: TObject): TStringList; var Count, Loop: Integer; List: TPropList; begin Result := TStringList.Create; Count := GetPropList(PTypeInfo(Obj.ClassInfo), tkAny, @List);
Result.BeginUpdate; for Loop := 0 to Pred(Count) do Result.Add(List[Loop]^.Name); Result.EndUpdate; end; |
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Di 06.07.10 12:30
Also bei mir tut
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| function GetProperties(Obj: TObject): TStringList; var Count, Loop: Integer; List: TPropList; begin Result := TStringList.Create; Count := GetPropList(PTypeInfo(Obj.ClassInfo), tkAny, @List);
Result.BeginUpdate; for Loop := 0 to Pred(Count) do Result.Add(List[Loop]^.Name); Result.EndUpdate; end; |
ohne Probleme (grad im Debugger nachgeschaut. Wobei: Deine TStringList ist nicht wirk,ich gegen Fehler geschützt. Try ... Except drum und im Fehlerfalle nil zurückgeben wäre praktisch ...
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
baka0815 
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Di 06.07.10 13:09
Hmm, woran könnte das denn liegen? Wenn ich GetProperties(TObject.Create) aufrufe - Speichermanagement, etc. ist erst einmal egal, da es nur Testcode ist - dann wird mir in GetProperties angezeigt, dass Obj.ClassInfo ein nil-Pointer ist.
Ich habe mir dafür sicherheitshalber den Code von dir raus kopiert.
Die Funktion ClassInfo macht bei mir folgendes:
Delphi-Quelltext 1:
| Result := PPointer(Integer(Self) + vmtTypeInfo)^; |
Ich habe schon versucht, das so nachzustellen. Ich bekomme auch eine Adresse ( PPointer(Integer(Self) + vmtTypeInfo)), wenn ich diese mit ^ dereferenziere, bekomme ich aber wieder nil -> stellt sich mir die Frage warum...
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Di 06.07.10 13:17
TObject hat keine published-Properties. Du brauchst eine Klasse, die von TPersistent abgeleitet ist.
Hab es it TApplication probiert.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Für diesen Beitrag haben gedankt: baka0815
|
|
baka0815 
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Di 06.07.10 14:05
Wenn ich TPersistent.Create statt TObject.Create verwende funktioniert alles bestens, also müssen auch meine Klassen entsprechend geändert werden und nicht mehr von TInterfacedObject, sondern von TInterfacedPersistent erben, korrekt?
Zumindest funktioniert das ganze so.
Gibt es für dieses Verhalten (Interface != Objekt, TObject != TPersistent) einen vernünftigen Grund?
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Di 06.07.10 17:21
Ja  Und der ist sogar dokumentiert
TObject ist im Status $H- compiliert und besitzt damit keine Typen-Informationen. Erst TPersistent ODER alle davon abgeleiteten Klassen besitzen diese. Für eigene, von TObject abgeleitete Klassen, kann man den $H+-Status aber auch manuell setzen.
Mehr Details dazu in der System.pas bei der Deklaration von TPersistent ...
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
baka0815 
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Mi 07.07.10 13:02
$H hat aber nichts mit den Typeninformationen zu tun!?
Meinst du vielleicht $M? Das wird aber doch automatisch hinzugefügt sobald ich eine published-Eigenschaft deklariere?!
Und da meine Klasse published-Eigenschaften besitzt, bekomme ich die Info dass {$M+} für RTTI hinzugefügt wird und trotzdem funktioniert es nicht wenn ich von TObject (bzw. TInterfacedObject) ableite - von TPersistent (bzw. TInterfacedPersistent) funktioniert.
|
|
guinnes
      
Beiträge: 182
Erhaltene Danke: 14
|
Verfasst: Mi 07.07.10 13:09
baka0815 hat folgendes geschrieben : | | Und da meine Klasse published-Eigenschaften besitzt, bekomme ich die Info dass {$M+} für RTTI hinzugefügt wird und trotzdem funktioniert es nicht wenn ich von TObject (bzw. TInterfacedObject) ableite - von TPersistent (bzw. TInterfacedPersistent) funktioniert. |
Published macht doch erst ab TPersistent Sinn, da TObject das Streaming-System von Delphi noch nicht unterstützt
|
|
baka0815 
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Mi 07.07.10 14:13
Ich brauche das Streaming-System ja eigentlich nicht und ich möchte die Klassen auch nicht serialisieren oder ähnliches, sondern nur per RTTI auf die Eigenschaften zugreifen. Ich finde es eh komisch, dass eben nur auf die published Eigenschaften zugegriffen werden kann (bin da von Java verwöhnt).
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 07.07.10 14:19
Jup, meinte $M; brauch die so selten
TPersistent implementiert das Streaming-System, das ist richtig. TPErsistent ist aber auch die erste Klasse, die Property-Typinfos besitzt (eben wegen diesem Schalter).
Für andere Klassen werden zwar die Published-Properties als Properties generiert, der Streaming-Mechanismus funktioniert aber nicht, weil eben die erweiterten Klassen-Infos nicht erzeugt werden
Wenn Du deine eigene Ableitung auch im Status $M+ generierst, sollte es auch mit einer von TObject abgeleiteten Klasse gehen.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
|