6

As I read here,

the VMT also contains a number of “magic” fields to support features such as parent class link, instance size, class name, dynamic method table, published methods table, published fields table, RTTI table, initialization table for magic fields, the deprecated OLE Automation dispatch table and implemented interfaces table

It looks like the VMT does not include a field which contains the unit name where the class is defined. Is there some 'compiler magic' involved?

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 回答