Вопрос по – Как я могу убедиться, что RTTI доступен для класса, не создавая его экземпляры?

6

Я недавно разместилвопрос на этом форуме просят совета относительно отсутствующей информации RTTI в исполняемом файле DXE2.

Этот пост был урезанной версией моего фактического дела. РРУЗ пришел на помощь, и поэтому урезанная версия была быстро разрешена. Первоначальная проблема, тем не менее, все еще остается, и поэтому я публикую ее полностью. & Quot; Главный & Quot ;:

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 без фактической реализации этого?

Update:

На стороне нет, я мог бы упомянуть, что если я пытаюсь получить TRttiType, используяTRttiContext.GetTypeжелаемый типis найденный. Таким образом, есть некоторые RTTI. ПроверкаTRttiType.IsPublic свойство, полученноеTRttiContext.GetType возвращает истинное значение, то есть извлекаемый тип является общедоступным (и, следовательно, его можно найти с помощьюTRttiContext.FindType).

Да, это подтверждено. Спасибо @LURD. :) conciliator
Они о той же теме, @Lurd, но они не дублируют друг друга. Этот вопрос спрашивает, что происходит. Этот спрашивает, как решить это без создания экземпляра. Rob Kennedy
Возможный дубликатDelphi 2010 RTTI - RttiContext.FindType, Класс никогда не используется в приложении и не обрабатывается компилятором. LU RD

Ваш Ответ

2   ответа
2

Я использовал {$ STRONGLINKTYPES ON} и работал очень хорошо. Поместите это в основной блок.

Error: User Rate Limit Exceeded
14

Добавьте ссылку на класс и убедитесь, что компилятор / компоновщик не может удалить ее из исполняемого файла.

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 к результирующей программе.

Error: User Rate Limit Exceeded conciliator
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded conciliator
Error: User Rate Limit Exceeded conciliator
Error: User Rate Limit Exceeded{$STRONGLINKTYPES ON}Error: User Rate Limit Exceeded

Похожие вопросы