當我讀到here類/ VMT地址,我怎樣才能得到一個類的單位名稱,如果我只有
的VMT還包含了一些「神奇」領域的支持功能 如父類的鏈接,例如大小,類名,動態方法 表,公佈的方法表,出版領域的表,RTTI表,因爲魔法領域 初始化表,棄用的OLE自動化 分派表和實現的接口表
它看起來像VMT不包含包含定義類的單元名稱的字段。是否存在一些「編譯器魔術」?
當我讀到here類/ VMT地址,我怎樣才能得到一個類的單位名稱,如果我只有
的VMT還包含了一些「神奇」領域的支持功能 如父類的鏈接,例如大小,類名,動態方法 表,公佈的方法表,出版領域的表,RTTI表,因爲魔法領域 初始化表,棄用的OLE自動化 分派表和實現的接口表
它看起來像VMT不包含包含定義類的單元名稱的字段。是否存在一些「編譯器魔術」?
我看不出爲什麼VMT應該在這裏介入。 TObject已經爲此暴露了class function UnitName
。
VMT包括一個指針,指向類RTTI(由ClassInfo
方法提供);類RTTI包含一個類的單元名稱。作爲一個練習,你可以從VMT指針得到單位名稱,我寫了這個(德爾福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;
正如你所提到的那樣,RTTI指針可以從'ClassInfo'方法中使用,爲什麼你要證明這樣一個迂迴路線以獲得相同的信息?你可以用'P:= TObj.ClassInfo'替換所有的代碼。 –
@RobKennedy - 你不能直接調用'ClassInfo'方法只有一個指向未知類的VMT的指針。你可能會嘗試以某種方式改寫VMT指針,但我還沒有找到如何去做。 – kludg
@Serg只需將vmt指針轉換爲'TClass'即可。然後你可以做一個單行:'TypInfo.GetTypeData(TClass(vmt).ClassInfo).UnitName' –
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必須爲零進行測試。例如。 SysUtils.ERangeError沒有它。
對於早於D2009的版本,可以使用'typinfo.GetTypeData(TSomeClass.ClassInfo).UnitName' –