我最近在此论坛上发布了question,以寻求有关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();
...
所以我想知道,有什么方法可以强制为
TMyClass
发出RTTI而不实际实例化它?更新:
另一方面,我可能会提到,如果我尝试使用
TRttiContext.GetType
来获取TRttiType,则会找到所需的类型。因此,发出了一些RTTI。检查TRttiType.IsPublic
检索到的TRttiContext.GetType
属性会产生一个真值,即,检索到的类型是public(因此应该可以使用TRttiContext.FindType
定位)。 最佳答案
添加对该类的引用,并确保编译器/链接器无法将其从可执行文件中剥离。
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添加到生成的程序中。关于delphi - 如何确定RTTI是否可用于某个类而无需实例化它?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10613094/