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

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

5 ответов

Решение

Какую структуру 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 и ранее) на всех объектах TO, которые отрицательно смещены от самого указателя VMT.

Это причина для ссылки vmtParent.

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

Я был почти уверен, что у Халварда было что-то на ВМТ. Конечно же, у него есть Hack #8: явные вызовы VMT, которые ссылаются на секреты Рэя Лишнера Delphi 2 и Delphi в двух словах.

Вот его взломанная версия 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;

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

Я подключу свой собственный сайт для этого:

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

Я думаю, что это точно на Delphi 2005.

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

Поиск в Google:-P для "delphi vmt" дает это. Может быть, это дает вам начало.

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

Другие вопросы по тегам