2012-06-30 25 views
6

Khi tôi đọc here,Làm thế nào tôi có thể nhận được tên đơn vị của một lớp nếu tôi có địa chỉ lớp/VMT chỉ

các VMT cũng chứa một số lĩnh vực “ma thuật” để hỗ trợ các tính năng như lớp liên kết phụ huynh, kích thước Ví dụ, tên lớp, phương pháp năng động bảng, công bố phương pháp bảng, được công bố lĩnh vực bảng, RTTI bảng, bảng khởi tạo cho các lĩnh vực ma thuật, các phản OLE Automation bảng công văn và giao diện được cài bảng

Dường như VMT không bao gồm một trường chứa tên đơn vị nơi lớp được xác định. Có một số 'ma thuật biên dịch' có liên quan?

Trả lời

9

Tôi không thể thấy tại sao VMT nên được tham gia ở đây. TObject đã hiển thị một số class function UnitName cho điều đó.

System.TObject.UnitName

+9

Đối với các phiên bản cũ hơn D2009, người ta có thể sử dụng 'typinfo.GetTypeData (TSomeClass.ClassInfo) .UnitName' –

1

VMT bao gồm một con trỏ đến lớp RTTI (cung cấp bởi ClassInfo phương pháp); lớp RTTI bao gồm tên đơn vị lớp. Như một bài tập bạn có thể nhận được tên đơn vị từ VMT con trỏ, tôi viết bài này (thử nghiệm trên 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

Vì, như bạn đề cập, con trỏ RTTI có sẵn trong phương thức' ClassInfo' tuyến đường để có được thông tin rất giống nhau? Bạn có thể thay thế tất cả mã đó bằng 'P: = TObj.ClassInfo'. –

+0

@RobKennedy - Bạn không thể gọi phương thức 'ClassInfo' trực tiếp chỉ có một con trỏ tới VMT của lớp chưa biết. Bạn có thể cố gắng để đánh máy con trỏ VMT bằng cách nào đó, nhưng tôi đã không tìm thấy làm thế nào để làm điều đó. – kludg

+4

@Serg Chỉ cần đưa con trỏ vmt vào 'TClass'. Sau đó, bạn có thể tạo một lớp lót: 'TypInfo.GetTypeData (TClass (vmt) .ClassInfo) .UnitName' –

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; 

Lưu ý rằng ClassInfo phải được kiểm tra nil. Ví dụ. SysUtils.ERangeError không có nó.

Các vấn đề liên quan