Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi [RTTI] Setter und Getter einer Property (https://www.delphipraxis.net/149803-%5Brtti%5D-setter-und-getter-einer-property.html)

s.h.a.r.k 30. Mär 2010 16:22


[RTTI] Setter und Getter einer Property
 
Hallo zusammen,

und schon wieder hänge ich mal an einem Problem mit RTTI :stupid: ich würde gerne herausfinden, ob eine Property eine Setter und Getter-Methode hat und wenn ja, will ich deren Adresse haben. Ich habe schon folgenden Versuch unternommen, aber bin nicht wirklich zu einem Ergebnis gelangt:

Delphi-Quellcode:
//
// Hier erst mal die Klasse, die ich zum Testen erstellt habe
//

TBlub = class(TObject)
private
  FTest : String;
  function GetTest(): String;
public
  procedure SetTest(const AValue: String);
  property Test : String read GetTest write SetTest;
end;

procedure TBlub.SetTest(const AValue: String);
begin
  if (FTest <> AValue) then
    FTest := AValue;
end;


//
// Hier nun der eigentliche Code
//

var
  rContext : TRttiContext;
  rType : TRttiType;
  rProp : TRttiProperty;
  rMethod : TRttiMethod;

  obj : TBlub;
begin
  rContext := TRttiContext.Create();
  obj := TBlub.Create;
  try
    rType := rContext.GetType(TBlub);

    // Adresse von SetTest via GetMethod ausgeben
    Memo1.Lines.Add('SetTest-Address: ' + IntToStr(Integer(rType.GetMethod('SetTest').CodeAddress)) );

    for rProp in rType.GetProperties do
    begin
      // Property samt Getter und Setter-Methoden-Adressen ausgeben
      Memo1.Lines.Add(rProp.Name + ':');
      Memo1.Lines.Add(PPropInfo(rProp.Handle).Name + '-Get: ' + IntToStr(Integer(PPropInfo(rProp.Handle).GetProc)));
      Memo1.Lines.Add(PPropInfo(rProp.Handle).Name + '-Set: ' + IntToStr(Integer(PPropInfo(rProp.Handle).SetProc)));
    end;
  finally
    FreeAndNil(obj);
    rContext.Free();
  end;
end;
Folgende Zeilen kommen dabei raus:

Code:
SetTest-Address: 4894124
Test:
-Get: 33554944
-Set: 1074941952
Zum einen ist es so, dass die PPropInfo mit gar keinen Namen für die Methode liefert, was ich schon seltsam finde und zum anderen die Adressen der Setter-Methode nicht annähernd gleich sind.

Kann mir hier jemand helfen? Ich sehe wohl den Wald vor lauter Bäumen nicht :wall:

s.h.a.r.k 31. Mär 2010 12:04

Re: [RTTI] Setter und Getter einer Property
 
*push*

chaosben 31. Mär 2010 12:17

Re: [RTTI] Setter und Getter einer Property
 
[wenig_hilfreiche_Antwort]
Über die guten alten RTTI-Funktionen gehts wunderbar:
Delphi-Quellcode:
  uses uRTTIHelper;

  TBlub = class(TObject)
  private
    FTest : String;
    function GetTest(): String;
  public
    procedure SetTest(const AValue: String);
  published
    property Test : String read GetTest write SetTest;
  end;

var
  ppi : PPropInfo;
begin
  ppi := rttihGetPropertyByName(TBlub, 'Test');
  Edit1.Text := Format('Getter: %p / Setter: %p', [ppi^.GetProc, ppi^.SetProc]);
end;
Code:
Getter: 004644A8 / Setter: 004644BC
[/wenig_hilfreiche_Antwort]

s.h.a.r.k 31. Mär 2010 13:05

Re: [RTTI] Setter und Getter einer Property
 
Ich sag mal so, besser als nix :thumb: uRTTIHelper bekomme ich wo her? Diese Unit kommt doch irgendwie von dir, soweit ich das noch recht in Erinnerung habe, oder?

//edit

Schon gefunden, nur hilft mir das im Moment nicht so wirklich weiter...

s.h.a.r.k 31. Mär 2010 21:46

Re: [RTTI] Setter und Getter einer Property
 
Wie folgt kann man den Pointer auf die Getter- und Setter-Methode einer Property ermitteln.

Delphi-Quellcode:
var
  rContext : TRttiContext;
  rType : TRttiType;
  rProperty : TRttiProperty;
  rPropInfo : PPropInfo;
  pt : Pointer;
begin
  rContext := TRttiContext.Create();
  try
    rType := rContext.GetType(Self.ClassType);
    for rProperty in rType.GetDeclaredProperties do
    begin
      rPropInfo := TRttiInstanceProperty(rProperty).PropInfo;

      // Pointer auf Setter-Methode
      pt := rPropInfo.GetProc;

      // Pointer auf Getter-Methode
      pt := rPropInfo.GetProc;
     
      { ... }

    end;
  finally
    rContext.Free();
  end;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:57 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz