6

私がここで読んだように、

VMTには、親クラスリンク、インスタンスサイズ、クラス名、動的メソッドテーブル、公開メソッドテーブル、公開フィールドテーブル、RTTIテーブル、マジックフィールドの初期化テーブル、非推奨のOLEなどの機能をサポートする多数の「マジック」フィールドも含まれています。自動ディスパッチテーブルと実装されたインターフェイステーブル

VMTには、クラスが定義されているユニット名を含むフィールドが含まれていないようです。「コンパイラの魔法」が関係していますか?

4

3 に答える 3

11

VMTがここに関与する必要がある理由がわかりません。TObjectはすでにそのためのを公開しclass function UnitNameています。

System.TObject.UnitName

于 2012-06-30T11:09:42.687 に答える
1

VMTには、クラスRTTI(ClassInfoメソッドによって提供される)へのポインターが含まれています。クラスRTTIには、クラスユニット名が含まれています。演習として、VMTポインターからユニット名を取得できます。これを作成しました(Delphi XEでテスト済み)。

uses TypInfo;

type
  TObj = class

  end;

procedure TForm1.Button3Click(Sender: TObject);
var
  Obj: TObj;    //  dummy obj instance
  VMT: Pointer;
  P: Pointer;   // class info

begin
// you can get VMT pointer so
  Obj:= TObj.Create;
  VMT:= PPointer(Obj)^;
  Obj.Free;
// or so
  VMT:= Pointer(TObj);

  P:= PPointer(PByte(VMT) + vmtTypeInfo)^;
  if P <> nil then
    ShowMessage(GetTypeData(P).UnitName);
end;
于 2012-06-30T13:00:59.957 に答える
0
procedure MessageException(E: Exception);
var
  TI: TypInfo.PTypeInfo;
begin
  TI := E.ClassInfo;
  if Assigned(TI) then
  begin
    Dialogs.MessageDlg(TypInfo.GetTypeData(TI).UnitName + '.' +
      E.ClassName + ': ' + E.Message, Dialogs.mtError, [Dialogs.mbOK], 0, Dialogs.mbOK);
  end
  else
  begin
    Dialogs.MessageDlg(E.ClassName + ': ' + E.Message, Dialogs.mtError, [Dialogs.mbOK], 0, Dialogs.mbOK);
  end;
end;

ClassInfoはnilについてテストする必要があることに注意してください。たとえば、SysUtils.ERangeErrorにはありません。

于 2017-08-26T02:14:46.610 に答える