Es wird wieder etwas esoterisch. Angenommen ich habe folgende zwei Klassen:
Delphi-Quellcode:
TBase = class
procedure testMethod(); virtual;
end;
TSub = class(TBase)
procedure testMethod(); override;
end;
und lasse einen
TVirtualMethodInterceptor
aus
System.Rtti
darauf los:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
obj := TSub.Create();
interceptor := TVirtualMethodInterceptor.Create( obj.ClassType() );
interceptor.OnAfter := interceptAfter;
interceptor.Proxify(obj);
obj.testMethod();
end;
procedure TForm1.interceptAfter(Instance: TObject; Method: TRttiMethod; const Args: TArray<TValue>; var Result: TValue);
begin
if Method.CodeAddress = Addr(TBase.testMethod) then
ShowMessage('After base method');
if Method.CodeAddress = Addr(TSub.testMethod) then
ShowMessage('After sub method');
end;
Dann bekomme ich leider ein
ShowMessage('After base method');
. Für die
OnBefore
oder
OnException
-Handler des
TVirtualMethodInterceptor
verhält es sich ebenso.
Wie kann ich feststellen dass
TSub.testMethod()
ausgeführt wird? Ich hatte den Compiler im Verdacht dass er mir hier das inlined und es in Wirklichkeit keine virtuelle Methode ist. Wirklich prüfen und beweisen könnte ich das aber wahrscheinlich nur wenn ich mit Assemblercode lesen könnte.
PS: Leicht ähnliches Thema:
https://www.delphipraxis.net/193681-...rgleichen.html
Meine Motivation ist dass halt bei einer bestimmten Methode dazwischen grätschen will und der String-Vergleich mit
Method.Name
echt unschön ist.
Method.CodeAddress
sieht da gleich viel besser aus, das funktioniert ja auch wenn jemand die Methode umbenennt.
PPS: Ich bin mir generell unsicher ob das Statement
Addr(TBase.testMethod)
überhaupt richtig ist. Angenommen, ich überlade testMethod(). Auf was Zeigt Addr(TBase.testMethod) dann eigentlich?