How can I find index of procedure/function which is defined in Interface? Can it be done with RTTI?
Asked
Active
Viewed 441 times
1 Answers
3
First of all we need to enumerate the methods of the interface. Unfortunately this program
{$APPTYPE CONSOLE}
uses
System.SysUtils, System.Rtti;
type
IMyIntf = interface
procedure Foo;
end;
procedure EnumerateMethods(IntfType: TRttiInterfaceType);
var
Method: TRttiMethod;
begin
for Method in IntfType.GetDeclaredMethodsdo
Writeln('Name: ' + Method.Name + 'Index: ' + IntToStr(Method.VirtualIndex));
end;
var
ctx: TRttiContext;
begin
EnumerateMethods(ctx.GetType(TypeInfo(IMyIntf)) as TRttiInterfaceType);
end.
produces no output.
This question covers this issue: Delphi TRttiType.GetMethods return zero TRttiMethod instances.
If you read down to the bottom of that question an answer states that compiling with {$M+}
will lead to sufficient RTTI being emitted.
{$APPTYPE CONSOLE}
{$M+}
uses
System.SysUtils, System.Rtti;
type
IMyIntf = interface
procedure Foo(x: Integer);
procedure Bar(x: Integer);
end;
procedure EnumerateMethods(IntfType: TRttiInterfaceType);
var
Method: TRttiMethod;
begin
for Method in IntfType.GetDeclaredMethods do
Writeln('Name: ' + Method.Name + 'Index: ' + IntToStr(Method.VirtualIndex));
end;
var
ctx: TRttiContext;
begin
EnumerateMethods(ctx.GetType(TypeInfo(IMyIntf)) as TRttiInterfaceType);
end.
The output is:
Name: FooIndex: 3 Name: BarIndex: 4
Remember that all interfaces derive from IInterface
. So one might expect its members to appear. However, it seems that IInterface
is compiled in {$M-}
state. It also seems that the methods are enumerated in order, although I've no reason to believe that is guaranteed.
Thanks to @RRUZ for pointing out the existence of VirtualIndex
.

Community
- 1
- 1

David Heffernan
- 601,492
- 42
- 1,072
- 1,490
-
Makes me wonder how inherited/overridden ones would be listed. – Jerry Dodge Jan 15 '15 at 17:29
-
@JerryDodge We are talking about interfaces – David Heffernan Jan 15 '15 at 17:30
-
Yes, I know this. Interfaces can be inherited (and redeclared methods rather) – Jerry Dodge Jan 15 '15 at 17:35
-
@Jerry You said overridden. And interface inheritance isn't much more than adding extra functions on the end of the parent interface. – David Heffernan Jan 15 '15 at 17:36
-
1@DavidHeffernan, you can use the `VirtualIndex` property to get the index of the method like so `Writeln(Format('Name: %s Index %d', [Method.Name, Method.VirtualIndex]));` – RRUZ Jan 15 '15 at 19:08
-
@RRUZ Can you make an example with actual interface? :) – John Lewis Jan 15 '15 at 19:24
-
1@John Just add that code into the code in my answer. I'll update it soon. – David Heffernan Jan 15 '15 at 19:32