Delphi RTTI无法找到界面

con*_*tor 4 delphi interface rtti

我正在尝试使用D2010 RTTI获取接口.

program rtti_sb_1;
{$APPTYPE CONSOLE}
{$M+}
uses
  SysUtils,
  Rtti,
  mynamespace in 'mynamespace.pas';
var
  ctx:      TRttiContext;
  RType:    TRttiType;
  MyClass:  TMyIntfClass;
begin
  ctx := TRttiContext.Create;
  MyClass := TMyIntfClass.Create;
  // This prints a list of all known types, including some interfaces.
  // Unfortunately, IMyPrettyLittleInterface doesn't seem to be one of them.
  for RType in ctx.GetTypes do
    WriteLn(RType.Name);
  // Finding the class implementing the interface is easy.
  RType := ctx.FindType('mynamespace.TMyIntfClass');
  // Finding the interface itself is not.
  RType := ctx.FindType('mynamespace.IMyPrettyLittleInterface');
  MyClass.Free;
  ReadLn;
end.
Run Code Online (Sandbox Code Playgroud)

双方IMyPrettyLittleInterfaceTMyIntfClass = class(TInterfacedObject, IMyPrettyLittleInterface)声明中mynamespace.pas,特别是

unit mynamespace;
interface
type
  IMyPrettyLittleInterface = interface
    ['{6F89487E-5BB7-42FC-A760-38DA2329E0C5}']
  end;
  TMyIntfClass = class(TInterfacedObject, IMyPrettyLittleInterface)
  end;
  //...
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么这不起作用?有办法解决我的问题吗?提前致谢!

Rob*_*ove 7

这是你发现的一种奇怪的行为.您可以使用以下方式找到类型:

RType := ctx.GetType(TypeInfo(IMyPrettyLittleInterface));
Run Code Online (Sandbox Code Playgroud)

但是,在您完成此操作后,您可以按名称访问它,因此如果您需要通过Name访问它,您可以执行以下操作以使其正常工作.

示例程序:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Rtti,
  TypInfo,
  Unit1 in 'Unit1.pas';

var
 ctx : TRttiContext;
 IType : TRttiType;
begin;
  ctx := TRttiContext.Create;
  IType := ctx.FindType('Unit1.IExample');
  if Assigned(IType) then
  begin
    writeln('Found');
    Writeln(IType.QualifiedName);
  end
  else
    writeln('Not Found');
  ReadLn;
end.
Run Code Online (Sandbox Code Playgroud)

示例单位:

unit Unit1;

interface

type
  IExample = interface
    ['{D61F3245-13FB-44BF-A89D-BB358FAE7D19}']
  end;

implementation
uses Rtti;
var
 C : TRttiContext;

initialization
 C.GetType(TypeInfo(IExample));

end.
Run Code Online (Sandbox Code Playgroud)


Bar*_*lly 7

问题是VMT和实现接口的类的typeinfo都不包含对这些接口的typeinfo的任何引用.然后,如果程序中没有另外引用,则链接器将删除接口的typeinfo.要解决这个问题,需要对类进行typeinfo格式更改以引用已实现的接口的typeinfo,否则所有接口都需要强烈链接到可执行文件中.其他类型的修复,例如由链接类实现而不实际包含类typeinfo中的引用的强链接接口,由于编译器的集成智能链接器如何工作而存在问题.

解决此问题的另一种方法是使用该指令{$STRONGLINKTYPES ON}.这将导致EXE,BPL或DLL的根类型表中的所有类型(允许RTL将限定名称映射到类型的索引)与强修正而不是弱修正相关联.智能链接器消除了只有弱修正引用它们的符号; 如果一个或多个强大的修正引用了该符号,那么它将包含在最终的二进制文件中,并且弱引用不会被取消(实际上是@PointerToNil).

如其他答案中所述,TypeInfo(ITheInterface)在非死代码中修复了问题; 这是因为TypeInfo()魔术函数为界面创建了强大的修正.