Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: RttiType.getMethods return me all parent methods, even abstract methods :(


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 5 - Last Post: Oct 24, 2015 3:17 PM Last Post By: Remy Lebeau (Te...
loki loki

Posts: 787
Registered: 7/1/02
RttiType.getMethods return me all parent methods, even abstract methods :(  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 22, 2015 4:36 AM
Hello,

RTTI getmethods return me all the methods, even the virtual/abstract method declared in parent class and overidden in the current class !

ex

TMyObject
procedure A; virtual; abstract;
end

TmyChildObject = class(TmyObject);
procedure A; override;
end

RttiTypeOfTmyChildObject.getMethods return me :
A (codeAdress xxx)
A (codeAdress yyy)

but i don't need the method of the parent (because it's overriden in the current class)
how i can do ?

thanks you by advance
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: RttiType.getMethods return me all parent methods, even abstract methods:(  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 22, 2015 10:54 AM   in response to: loki loki in response to: loki loki
loki wrote:

RTTI getmethods return me all the methods, even the virtual/abstract
method declared in parent class and overidden in the current class !

It is supposed to, by design. GetMethods() retreives ALL available methods.
That is its documented purpose:

http://docwiki.embarcadero.com/Libraries/en/System.Rtti.TRttiType.GetMethods

Returns a list of all the methods that are part of the reflected type.

Use the GetMethods method to obtain a list of all the methods that are members
of the reflected type.
...
The list returned by GetMethods is ordered by the class/interface hierarchy.
This means that the most recently included methods are located at the top
of the list.

but i don't need the method of the parent (because it's overriden in
the current class) how i can do ?

Use GetDeclaredMethods() instead:

http://docwiki.embarcadero.com/Libraries/en/System.Rtti.TRttiType.GetDeclaredMethods

Returns a list of all the methods declared in the reflected type.

Use the GetDeclaredMethods method to obtain a list of all the methods that
are declared in the reflected type. To obtain the list of all the methods
in the reflected type (including the inherited ones), use the GetMethods
method instead.

--
Remy Lebeau (TeamB)
loki loki

Posts: 787
Registered: 7/1/02
Re: RttiType.getMethods return me all parent methods, even abstract methods:(  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 22, 2015 12:47 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
no getdeclaredmethod is completely useless !!

TobjectA
public
proc A
end;

TobjectB = class(TobjectA)
end;

of couse on TobjectB getdeclaredmethod will return me nothing :( :(
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: RttiType.getMethods return me all parent methods, even abstractmethods:(  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 22, 2015 1:11 PM   in response to: loki loki in response to: loki loki
loki wrote:

no getdeclaredmethod is completely useless !!

TobjectA
public
proc A
end;
TobjectB = class(TobjectA)
end;

of couse on TobjectB getdeclaredmethod will return me nothing :( :(

Right, because TObjectB does not declare any methods. But that is not what
you asked for. You said earlier that your derived classes are overriding
virtual methods. That means they have method declarations which should appear
in GetDeclaredMethods(). Any given method of a class is either declared
or inherited, thus retreivable from GetDeclaredMethods() or GetMethods(),
respectively. I don't see a problem here. What exactly are you trying to
solve that you are having difficulty with?

--
Remy Lebeau (TeamB)
loki loki

Posts: 787
Registered: 7/1/02
Re: RttiType.getMethods return me all parent methods, even abstractmethods:(  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 23, 2015 2:58 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Right, because TObjectB does not declare any methods. But that is not what
you asked for. You said earlier that your derived classes are overriding
virtual methods. That means they have method declarations which should appear
in GetDeclaredMethods(). Any given method of a class is either declared
or inherited, thus retreivable from GetDeclaredMethods() or GetMethods(),
respectively. I don't see a problem here. What exactly are you trying to
solve that you are having difficulty with?

it's simply, i want to replace all rtti invoke, GetValue, SetValue by all typeinfo function like SetOrdProp, GetOrdProp, etc... why ? because regarding this article http://www.armin-pfaeffle.de/blog/2010/06/rtti-in-delphi-2010-nice-but-a-little-bit-too-slow/ and executing the demo you will see that rtti is very slow :(

but the problem is that old typeinfo can not let you read/write to for exemple indexed properties :( but not a big deal because you can use in this way the getter/setter to read and write to indexed properties!
instead of doing invoke, i use Tmethod

Tgetter = function(const index: integer): integer of object;

aMethod: Tmethod;
aMethod.code := MyRttiIndexedProperty.readMethod.codeAddress;
aMethod.data := MyObject;
result := TGetter(aMethod)(xxx);

that work perfectly BUT not perfect of the perfect because in some scenario MyRttiIndexedProperty.readMethod.codeAddress return the code adress in the base class (even abstract) ..

actually i do like this, not sure if it's good :

{**}
type
PVtable = ^TVtable;
TVtable = array[0..MaxInt div SizeOf(Pointer) - 1] of Pointer;

function GetFinalCodeAddress(Cls: TClass; aRttiMethod: TRttiMethod): Pointer;
begin
if IsStatic then result := aRttiMethod.CodeAddress
else begin
case DispatchKind of
dkVtable: result := PVtable(Cls)^[aRttiMethod.VirtualIndex];
dkDynamic: result := GetDynaMethod(Cls, aRttiMethod.VirtualIndex);
else result := aRttiMethod.CodeAddress; //dkStatic => not virtual nor dynamic method
//dkMessage => never possible here
//dkInterface => never possible here

end;
end;
end;
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: RttiType.getMethods return me all parent methods, evenabstractmethods:(  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 24, 2015 3:17 PM   in response to: loki loki in response to: loki loki
loki wrote:

in some scenario MyRttiIndexedProperty.readMethod.codeAddress
return the code adress in the base class (even abstract) ..

If a property getter is an abstract method, a descendant class must override
it. When reading a property "normally" (not through RTTI), the compiler
would detect the virtual/abstract nature of the getter and generate proper
code to invoke the descendant method via polymorphism. You can't use the
TRttiMethod.CodeAddress value when the TRttiMethod.DispatchKind is dkVtable
or dkDynamic, for instance. To call a method via TRttiMethod, you should
be using TRttiMethod.Invoke(), which takes these details into account.
If you really want to use TMethod directly, you have to obtain the proper
code address, and the way to do that what you already discovered - using
the TRttiMethod.VirtualIndex value to index into the object's VMT or Dispatch
table, depending on the TRttiMethod.DispatchKind value.

actually i do like this, not sure if it's good :

That is essentially what TRttiMethod.Invoke() does internally to find the
correct code address.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02