¿Cómo puedo asegurarme de que RTTI esté disponible para una clase sin crear una instancia?
Recientemente he publicado unpregunta en este foro, solicite cualquier consejo con respecto a la información RTTI faltante en un ejecutable DXE2.
Esa publicación fue una versión simplificada de mi caso real. RRUZ vino al rescate, por lo que la versión reducida se resolvió rápidamente. Sin embargo, el problema original sigue en pie, por lo que ahora lo estoy publicando en su totalidad. "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.
y finalmenteMyUnit.pas
:
unit MyUnit;
interface
type
TMyClass = class(TObject)
end;
implementation
end.
No se encuentra el tipo deseado. Sin embargo, si cambioTRttiHelper.IsTypeFound
de modo que ejemplifique (y libere inmediatamente) una instancia deTMyClass
, se encuentra el tipo. Al igual que:
function TRttiHelper.IsTypeFound(TypeName: string): boolean;
var
rCtx: TRttiContext;
rType: TRttiType;
MyObj: TMyClass;
begin
Result := false;
MyObj:= TMyClass.Create();
MyObj.Free();
rCtx := TRttiContext.Create();
...
Así que me pregunto, ¿hay alguna manera de forzar la emisión de RTTI paraTMyClass
sin en realidad instanciarlo?
Actualizar:
Por un lado no, podría mencionar que si intento obtener el TRttiType usandoTRttiContext.GetType
, el tipo deseadoes encontró. Así que hay algunos RTTI emitidos. Revisando elTRttiType.IsPublic
propiedad recuperada porTRttiContext.GetType
produce un valor verdadero, es decir, el tipo recuperado es público (y por lo tanto debería ser posible ubicarlo usandoTRttiContext.FindType
).