Подтвердить что ты не робот

Где я могу найти информацию о структуре Delphi VMT?

В файле System.pas содержится достаточное количество информации о смещенных смещениях VMT, но, похоже, он фактически не говорит о структуре самого VMT. Мне бы хотелось узнать, есть ли способ узнать размер VMT во время выполнения, или, другими словами, сколько виртуальных методов существует для данного класса?

4b9b3361

Ответ 1

Как насчет структуры VMT, которую вы хотите знать? Вы также знаете, что это внутренняя деталь реализации, которая может быть изменена (и со временем изменилась).

Чтобы ответить на ваш конкретный вопрос, вот простой способ найти количество виртуальных методов для данного класса:

function GetVirtualMethodCount(AClass: TClass): Integer;
begin
  Result := (PInteger(Integer(AClass) + vmtClassName)^ - 
    (Integer(AClass) + vmtParent) - SizeOf(Pointer)) div SizeOf(Pointer);
end;

Это работает, потому что я знаю, что строка, представляющая имя класса, помещается сразу же после всех векторов виртуальных методов в VMT.

Я также знаю, что существует 11 виртуальных методов (для D2009, 9 для D2007 и ранее) для всех TObject, которые отрицательно смещены от самого указателя VMT.

В этом причина ссылки vmtParent.

Наконец, используя ссылку класса TClass, вы можете передать любой производный класс TObject в эту функцию и получить количество виртуальных методов.

Ответ 2

Я был уверен, что у Hallvard есть что-то на VMT. Разумеется, он Hack # 8: Явные вызовы VMT, которые в двух словах описывают тайны Delphi 2 и Delphi Ray Lischner.

Вот его взломанная версия VMT

type
  PClass = ^TClass;
  PSafeCallException = function  (Self: TObject; ExceptObject:
    TObject; ExceptAddr: Pointer): HResult;
  PAfterConstruction = procedure (Self: TObject);
  PBeforeDestruction = procedure (Self: TObject);
  PDispatch          = procedure (Self: TObject; var Message);
  PDefaultHandler    = procedure (Self: TObject; var Message);
  PNewInstance       = function  (Self: TClass) : TObject;
  PFreeInstance      = procedure (Self: TObject);
  PDestroy           = procedure (Self: TObject; OuterMost: ShortInt);
  PVmt = ^TVmt;
  TVmt = packed record
    SelfPtr           : TClass;
    IntfTable         : Pointer;
    AutoTable         : Pointer;
    InitTable         : Pointer;
    TypeInfo          : Pointer;
    FieldTable        : Pointer;
    MethodTable       : Pointer;
    DynamicTable      : Pointer;
    ClassName         : PShortString;
    InstanceSize      : PLongint;
    Parent            : PClass;
    SafeCallException : PSafeCallException;
    AfterConstruction : PAfterConstruction;
    BeforeDestruction : PBeforeDestruction;
    Dispatch          : PDispatch;
    DefaultHandler    : PDefaultHandler;
    NewInstance       : PNewInstance;
    FreeInstance      : PFreeInstance;
    Destroy           : PDestroy;
   {UserDefinedVirtuals: array[0..999] of procedure;}
  end;

Вам нужно будет прочитать его статью, чтобы узнать больше о хаке.

Ответ 3

Googling: -P для "delphi vmt" дает this. Возможно, это дает вам начало.

Ответ 4

Я закрою свой сайт для этого:

Что такое таблица виртуальных методов?

Это точно, как в Delphi 2005, я думаю.

У VMT нет никакого значения, указывающего количество указателей виртуального метода, которые он удерживает. Ничто, кроме компилятора, не должно знать эту информацию, поэтому нет причин записывать ее для использования во время выполнения.

Ответ 5

Я помню, что была некоторая информация о delphi vmt в книге "Дельфы в двух словах". u может начинаться с delphi в двух словах глава 2 или this