7

最近、このフォーラムに質問を投稿し、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を強制的に発行できる方法はありますか?

アップデート:

反対に、 を使用して TRttiType をフェッチしようとするとTRttiContext.GetType、目的の型見つかることを言及するかもしれません。したがって、いくつかの RTTI が放出されます。TRttiType.IsPublicによって取得されたプロパティをチェックするTRttiContext.GetTypeと、真の値が得られます。つまり、取得された型は public です (したがって、 を使用して特定できるはずですTRttiContext.FindType)。

4

2 に答える 2

16

クラスへの参照を追加し、コンパイラ/リンカーが実行可能ファイルから削除できないことを確認します。

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 が追加されます。

于 2012-05-16T06:36:37.333 に答える
3

I used {$STRONGLINKTYPES ON} and worked very well. Put it on main unit.

于 2015-09-19T22:23:06.183 に答える