7

我最近在这个论坛上发布了一个问题,询问有关 DXE2 可执行文件中缺少 RTTI 信息的任何建议。

那篇文章是我实际案例的精简版。RRUZ 前来救援,因此精简版很快得到解决。但是,最初的问题仍然存在,所以我现在将其完整发布。“主要的”:

program MissingRTTI;
{$APPTYPE CONSOLE}
uses
  System.SysUtils, RTTI, MyUnit in 'MyUnit.pas', RTTIUtil in 'RTTIUtil.pas';
var
  RHelp:  TRttiHelper;
begin
  RHelp := TRttiHelper.Create();
  if (RHelp.IsTypeFound('MyUnit.TMyClass')) then WriteLn('TMyClass was found.')
  else WriteLn('TMyClass was not found.');
  ReadLn;
  RHelp.Free();
end.

RTTIUtil.pas

unit RTTIUtil;
interface
uses
  MyUnit;
type
  TRttiHelper = class(TObject)
  public
    function IsTypeFound(TypeName: string) : boolean;
  end;
implementation
uses
  RTTI;
function TRttiHelper.IsTypeFound(TypeName: string): boolean;
var
  rCtx:   TRttiContext;
  rType:  TRttiType;
begin
  Result := false;
  rCtx := TRttiContext.Create();
  rType := rCtx.FindType(TypeName);
  if (rType <> nil) then
    Result := true;
  rCtx.Free();
end;
end.

最后MyUnit.pas

unit MyUnit;
interface
type
  TMyClass = class(TObject)
  end;
implementation
end.

未找到所需的类型。但是,如果我进行更改TRttiHelper.IsTypeFound以使其实例化(并立即释放) 的实例TMyClass,则会找到该类型。像这样:

function TRttiHelper.IsTypeFound(TypeName: string): boolean;
var
  rCtx:   TRttiContext;
  rType:  TRttiType;
  MyObj:  TMyClass;
begin
  Result := false;
  MyObj:= TMyClass.Create();
  MyObj.Free();
  rCtx := TRttiContext.Create();
  ...

所以我想知道,有什么方法可以强制发出 RTTI 而TMyClass无需实际实例化它?

更新:

另一方面,我可能会提到,如果我尝试使用 获取 TRttiType ,则会TRttiContext.GetType找到所需的类型。所以发出了一些RTTI。检查由检索到的属性会产生一个真值,即检索到的类型是公共的(因此应该可以使用 来定位)。TRttiType.IsPublicTRttiContext.GetTypeTRttiContext.FindType

4

2 回答 2

16

添加对该类的引用,并确保编译器/链接器无法将其从可执行文件中剥离。

unit MyUnit;

interface

type
  TMyClass = class(TObject)
  end;

implementation 

procedure ForceReferenceToClass(C: TClass);
begin
end;

initialization
  ForceReferenceToClass(TMyClass);

end.

在生产代码中,您可能希望将其放置ForceReferenceToClass在基本单元中以便可以共享。声明类的单元的初始化部分是最自然的调用位置,ForceReferenceToClass因为该单元是自包含的。

关于您GetType可以定位类型的观察,调用的行为GetType(TMyClass)将对该类型的引用添加到程序中。并不是说 RTTI 存在并且FindType找不到它。相反,包含GetType(TMyClass)将 RTTI 添加到生成的程序中。

于 2012-05-16T06:36:37.333 回答
3

我使用 {$STRONGLINKTYPES ON} 并且工作得很好。放在主机上。

于 2015-09-19T22:23:06.183 回答