Jak mogę się upewnić, że RTTI jest dostępna dla klasy bez jej tworzenia?
Ostatnio opublikowałempytanie na tym forum prosząc o radę dotyczącą brakujących informacji RTTI w pliku wykonywalnym DXE2.
Ten post był okrojoną wersją mojej rzeczywistej sprawy. RRUZ przyszedł na ratunek, więc uproszczona wersja została szybko rozwiązana. Pierwotny problem nadal jednak istnieje, więc teraz publikuję go w całości. "Główny":
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.
i w końcuMyUnit.pas
:
unit MyUnit;
interface
type
TMyClass = class(TObject)
end;
implementation
end.
Żądany typ nie został znaleziony. Jednak jeśli się zmienięTRttiHelper.IsTypeFound
tak, że tworzy instancję (i natychmiast zwalnia) wystąpienieTMyClass
, typ został znaleziony. Tak jak:
function TRttiHelper.IsTypeFound(TypeName: string): boolean;
var
rCtx: TRttiContext;
rType: TRttiType;
MyObj: TMyClass;
begin
Result := false;
MyObj:= TMyClass.Create();
MyObj.Free();
rCtx := TRttiContext.Create();
...
Zastanawiam się, czy w jakiś sposób mogę zmusić RTTI do emisjiTMyClass
bez tworzenia instancji?
Aktualizacja:
Z drugiej strony nie wspomnę, jeśli spróbuję pobrać TRttiType za pomocąTRttiContext.GetType
, pożądany typjest uznany. Jest więc emitowany RTTI. SprawdzanieTRttiType.IsPublic
nieruchomość jak odzyskana przezTRttiContext.GetType
daje prawdziwą wartość, tj. odzyskany typ jest publiczny (a zatem powinien być możliwy do zlokalizowania za pomocąTRttiContext.FindType
).