当我阅读here时,
VMT还包含许多支持功能的“魔术”字段 例如父类链接,实例大小,类名,动态方法 表,发布方法表,发布字段表,RTTI表, 魔术字段的初始化表,不推荐使用的OLE自动化 调度表和实现的接口表
看起来VMT不包含包含定义类的单元名称的字段。是否涉及一些“编译魔术”?
答案 0 :(得分:10)
我不明白为什么VMT应该参与其中。 TObject已经公开了class function UnitName
。
答案 1 :(得分:1)
VMT包含指向类RTTI的指针(由ClassInfo
方法提供); class 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;
答案 2 :(得分: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;
请注意,必须针对 nil 测试ClassInfo。例如。 SysUtils.ERangeError没有它。