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?
I cannot see why the VMT should be involved here. TObject already exposes a class function UnitName
for that.
VMT includes a pointer to class RTTI (provided by ClassInfo
method); class RTTI includes a class unit name. As an exercise you can get unit name from VMT pointer, I have written this (tested on 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;
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;
Note that ClassInfo must be tested for nil . Eg SysUtils.ERangeError does not have it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.