How to get class element name if I only have class / VMT address

As I read here ,

VMT also contains a number of "magic" fields for supporting functions, such as a reference to the parent class, instance size, class name, dynamic method table, published methods, published field table, RTTI table, initialization table for magic fields, outdated OLE automation distribution table and interface interfaces table

It appears that VMT does not contain a field that contains the name of the unit where the class is defined. Is there some kind of β€œcompiler magic”?

+6
source share
3 answers

I do not understand why VMT should be involved here. TObject already provides a class function UnitName for this.

System.TObject.UnitName

+9
source

VMT includes a pointer to the RTTI class (provided by the ClassInfo method); RTTI class includes the class name. As an exercise, you can get the unit name from the VMT pointer, I wrote 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; 
+1
source
 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 . For instance. SysUtils.ERangeError does not have this.

0
source

Source: https://habr.com/ru/post/919385/


All Articles