1

我最近能够使用 Robert Loves “GetType”-workaround(通过显式调用 ctx.GetType,例如 RType := ctx.GetType(TypeInfo( IMyPrettyLittleInterface));)。

一个合乎逻辑的下一步是迭代所述接口的方法。考虑

program rtti_sb_1;
{$APPTYPE CONSOLE}
uses
  SysUtils, Rtti, mynamespace in 'mynamespace.pas';
var
  ctx:      TRttiContext;
  RType:    TRttiType;
  Method:   TRttiMethod;
begin
  ctx := TRttiContext.Create;
  RType := ctx.GetType(TypeInfo(IMyPrettyLittleInterface));
  if RType <> nil then begin
    for Method in RType.GetMethods do
      WriteLn(Method.Name);
  end;
  ReadLn;
end.

这一次,我的mynamespace.pas样子是这样的:

IMyPrettyLittleInterface = interface
  ['{6F89487E-5BB7-42FC-A760-38DA2329E0C5}']
  procedure SomeProcedure;
end;

不幸的是,RType.GetMethods返回一个长度为零的 TArray 实例。有没有人能重现我的烦恼?(请注意,在我的示例中,我已使用 TRttiContext.GetType 显式获取 TRttiType,而不是解决方法;包含介绍是为了警告读者可能存在一些关于 rtti 和接口的未解决问题。)谢谢!

4

3 回答 3

2

我刚刚追踪了正在发生的事情,在 TRttiInterfaceType.Create 的第 5774 行中,它说:

hasRtti := ReadU16(P);
if hasRtti = $FFFF then
  Exit;

在你的接口和它继承的 IInterface 中,HasRtti 读取为 $FFFF。所以显然没有为接口的方法生成 RTTI,甚至对于基本接口类型也是如此。我不知道为什么。不知道谁会知道为什么,除了巴里凯利。

于 2010-06-09T12:43:46.003 回答
1

有时需要某些编译器指令来生成 RTTI,例如 M+。也许您只需要设置其中之一?

于 2010-06-09T15:18:02.753 回答
1

毕竟戴夫是对的。事实证明,接口必须由 {$M+}/{$M-} 子句包围。编译

{$M+}
IMyPrettyLittleInterface = interface
  ['{6F89487E-5BB7-42FC-A760-38DA2329E0C5}']
  procedure SomeProcedure;
end;
{$M-}

可以。

于 2010-06-10T08:25:57.803 回答