Delphi TRttiType.GetMethods возвращает ноль экземпляров TRttiMethod - PullRequest
1 голос
/ 09 июня 2010

Недавно я смог получить TRttiType для интерфейса, используя TRttiContext.FindType, используя 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 нулевой длины.Кто-нибудь может воспроизвести мои проблемы?(Обратите внимание, что в моем примере я явно выбрал TRttiType, используя TRttiContext.GetType, а не обходной путь; введение включено, чтобы предупредить читателей, что могут быть некоторые нерешенные проблемы, касающиеся rtti и интерфейсов.) Спасибо!

Ответы [ 3 ]

2 голосов
/ 09 июня 2010

Я только что проследил, что происходит, и в TRttiInterfaceType.Create, строка 5774, написано:

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

И в вашем интерфейсе, и в IInterface, от которого он наследуется, HasRtti читается как $ FFFF,Таким образом, очевидно, что RTTI не генерируется для методов интерфейса, и это даже верно для базового типа интерфейса.Я не знаю почему.Не уверен, кто знает, почему, кроме Барри Келли.

1 голос
/ 10 июня 2010

Дейв был прав в конце концов. Оказывается, интерфейс должен быть окружен предложением {$ M +} / {$ M -}. Компиляция с

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

делает это.

1 голос
/ 09 июня 2010

Существуют определенные директивы компилятора, иногда необходимые для генерации RTTI, такие как M +. Возможно, вам просто нужно установить один из них?

...