Como posso ter certeza de que o RTTI está disponível para uma turma sem instanciá-lo?
Eu postei recentemente umquestão neste fórum pedindo qualquer conselho sobre a falta de informações RTTI em um executável DXE2.
Esse post foi uma versão simplificada do meu caso real. A RRUZ veio em socorro e, assim, a versão simplificada foi rapidamente resolvida. O problema original, no entanto, ainda está de pé e, por isso, estou publicando tudo na íntegra agora. "A Principal":
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.
e finalmenteMyUnit.pas
:
unit MyUnit;
interface
type
TMyClass = class(TObject)
end;
implementation
end.
O tipo desejado não foi encontrado. No entanto, se eu mudarTRttiHelper.IsTypeFound
para que instancie (e imediatamente libere) uma instância deTMyClass
, o tipo é encontrado. Igual a:
function TRttiHelper.IsTypeFound(TypeName: string): boolean;
var
rCtx: TRttiContext;
rType: TRttiType;
MyObj: TMyClass;
begin
Result := false;
MyObj:= TMyClass.Create();
MyObj.Free();
rCtx := TRttiContext.Create();
...
Então, eu estou querendo saber, existe alguma maneira que eu possa forçar RTTI para ser emitido paraTMyClass
sem realmente instanciar isso?
Atualizar:
De um lado não, eu poderia mencionar que, se eu tentar buscar o TRttiType usandoTRttiContext.GetType
, o tipo desejadoé encontrado. Então, há algum RTTI emitido. Verificando oTRttiType.IsPublic
propriedade como recuperado porTRttiContext.GetType
produz um valor verdadeiro, ou seja, o tipo recuperado é público (e, portanto, deve ser possível localizar usandoTRttiContext.FindType
).