Список методов из VMT
От: Аноним  
Дата: 09.05.05 15:16
Оценка:
Вот дописываю оди интерпретатор ...
И для полного счасться мне не хватает всего лишь получить список методов для любого обьекта Delphi.
Подскажите кто нить , как его извлеч из VMT.

Заранее благодарен
Re: Список методов из VMT
От: Dimonka Верблюд  
Дата: 09.05.05 15:37
Оценка: -1
Здравствуйте, Аноним, Вы писали:

А>Вот дописываю оди интерпретатор ...

А>И для полного счасться мне не хватает всего лишь получить список методов для любого обьекта Delphi.
А>Подскажите кто нить , как его извлеч из VMT.

Как-как.. никак..
Люди пишут парсеры исходников и по ним строят обёртки для компонент / классов. В рантайме получить неопубликованные свойства классов не получится..
Re[2]: Список методов из VMT
От: Аноним  
Дата: 09.05.05 16:21
Оценка:
Здравствуйте, Dimonka, Вы писали:

D>Здравствуйте, Аноним, Вы писали:


А>>Вот дописываю оди интерпретатор ...

А>>И для полного счасться мне не хватает всего лишь получить список методов для любого обьекта Delphi.
А>>Подскажите кто нить , как его извлеч из VMT.

D>Как-как.. никак..

D>Люди пишут парсеры исходников и по ним строят обёртки для компонент / классов. В рантайме получить неопубликованные свойства классов не получится..

Мне не нужны свойства — мне нужны методы , а они все есть в VMT.
А делфовый rtti — позволяет узнать имя метода класса по указателю

TClass.MethodName(pinter);

Вот юзаю пример из Обработка абстрактных методов в Delphi
Автор(ы): Антон Злыгостев
Дата: 18.02.2003
Данная статья описывает метод получения дополнительной информации при вызове абстрактного метода во время выполнения. В Delphi такой вызов технически возможен и является ошибкой.
Стандартная библиотека лишь регистрирует факт возниконовения этой ошибки, не предоставляя никой информации о контексте. Предлагаемый метод позволяет выяснить имя класса и номера слотов VMT, соответствующих абстрактным методам.

а именно:


class function TAbstractHandler.DetectAbstracts(AClass: TClass;
  out Abstracts: TMIRArray): boolean;
var
  VMT: PPointer;
  VMTEnd: Pointer;
begin
  TClass(VMT):= AClass;
  VMTEnd:=GetVMTEnd(AClass);

  SetLength(Abstracts, 0);
  while (VMT<>VMTEnd) // Сканируем VMT
  do begin
    if IsMethodAbstract(VMT^)
    then begin
      SetLength(Abstracts, Length(Abstracts)+1); // Добавляем запись
      with Abstracts[High(Abstracts)] do
      begin
        VMTIndex:= (Integer(VMT)-Integer(AClass)) shr 2; // размер слота - 4 байта
        ClassType:= GetFirstDeclarator(AClass, VMTIndex);

        // вот тут и надо вписать что-то типа TClass(AClass).MethodName(Integer(VMT)+Integer(AClass)); или я ошибаюсь
      end;
    end;
    Inc(VMT);
  end;
  Result:= Length(Abstracts)>0; // Сигнализируем, успешен ли поиск.
end;
Re[3]: Список методов из VMT
От: Dimonka Верблюд  
Дата: 10.05.05 07:16
Оценка:
Ну и что тебе может дать имя метода без параметров и результата?
Re[3]: Список методов из VMT
От: Аноним  
Дата: 10.05.05 07:21
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Мне не нужны свойства — мне нужны методы , а они все есть в VMT.

А>А делфовый rtti — позволяет узнать имя метода класса по указателю

А>TClass.MethodName(pinter);


А>Вот юзаю пример из Обработка абстрактных методов в Delphi
Автор(ы): Антон Злыгостев
Дата: 18.02.2003
Данная статья описывает метод получения дополнительной информации при вызове абстрактного метода во время выполнения. В Delphi такой вызов технически возможен и является ошибкой.
Стандартная библиотека лишь регистрирует факт возниконовения этой ошибки, не предоставляя никой информации о контексте. Предлагаемый метод позволяет выяснить имя класса и номера слотов VMT, соответствующих абстрактным методам.


А там только published методы доступну.
Re[3]: Список методов из VMT
От: Danchik Украина  
Дата: 10.05.05 10:47
Оценка:
Здравствуйте, Аноним, Вы писали:

Что то типа этого ?

procedure GetMethodNames(aClass: TClass; List: TStrings);
type
  TMethodTable = packed record
    Count: SmallInt;
  //[...methods...]
  end;
var
  aTable : ^TMethodTable;
  aName  : ^ShortString;
  K      : Integer;
begin
  List.BeginUpdate;
  try
    while aClass <> nil do
    begin
      asm
        mov  EAX, [aClass]
        mov  EAX,[EAX].vmtMethodTable { fetch pointer to method table }
        mov  [aTable], EAX
      end;
      if aTable <> nil then
      begin
        aName  := Pointer(PChar(aTable) + 8);
        for K := 1 to aTable.Count do
        begin
          if List.IndexOf (aName^) < 0 then
            List.Add (aName^);
          aName := Pointer(PChar(aName) + length(aName^) + 7)
        end;
      end;
      aClass := aClass.ClassParent;
    end;
  finally
    List.EndUpdate;
  end;
end;


Учти, работает только в случае когда метод published
Re[4]: Список методов из VMT
От: ZendCoder  
Дата: 10.05.05 11:13
Оценка:
Здравствуйте, Danchik:

Да — но это не работает! И из VMT можно достать все!!! методы , кроме, если я не ошибаюсь , динамических .

Сразу после вызова aTable = nil

пишу GetMethodNames(TForm,memo1.Lines);

D>Здравствуйте, Аноним, Вы писали:


D>Что то типа этого ?


D>
D>procedure GetMethodNames(aClass: TClass; List: TStrings);
D>type
D>  TMethodTable = packed record
D>    Count: SmallInt;
D>  //[...methods...]
D>  end;
D>var
D>  aTable : ^TMethodTable;
D>  aName  : ^ShortString;
D>  K      : Integer;
D>begin
D>  List.BeginUpdate;
D>  try
D>    while aClass <> nil do
D>    begin
D>      asm
D>        mov  EAX, [aClass]
D>        mov  EAX,[EAX].vmtMethodTable { fetch pointer to method table }
D>        mov  [aTable], EAX
D>      end;
D>      if aTable <> nil then
D>      begin
D>        aName  := Pointer(PChar(aTable) + 8);
D>        for K := 1 to aTable.Count do
D>        begin
D>          if List.IndexOf (aName^) < 0 then
D>            List.Add (aName^);
D>          aName := Pointer(PChar(aName) + length(aName^) + 7)
D>        end;
D>      end;
D>      aClass := aClass.ClassParent;
D>    end;
D>  finally
D>    List.EndUpdate;
D>  end;
D>end;
D>


D>Учти, работает только в случае когда метод published
Re[5]: Список методов из VMT
От: Oleg A. Bachin Украина  
Дата: 10.05.05 12:54
Оценка:
Здравствуйте, ZendCoder, Вы писали:


ZC>Да — но это не работает! И из VMT можно достать все!!! методы , кроме, если я не ошибаюсь , динамических .


тебе ж по-русски сказали, только паблишед!!!

If Address does not point to a published method of the object, MethodName returns an empty string.

... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Best regards,
Oleg A. Bachin
Re[5]: Список методов из VMT
От: Danchik Украина  
Дата: 10.05.05 14:09
Оценка:
Здравствуйте, ZendCoder, Вы писали:

ZC>Здравствуйте, Danchik:


ZC>Да — но это не работает! И из VMT можно достать все!!! методы , кроме, если я не ошибаюсь , динамических .


ZC>Сразу после вызова aTable = nil


ZC>пишу GetMethodNames(TForm,memo1.Lines);


Елки палки. Фома ты неверующий.
Понаписывай свои методы, не published, сделай их вызовы (чтоб вкомпилилось) и попробуй поискать названия этих методов в EXE файле. Если найдеш:

Я съем свой котелок
Мистер Фикс (с)


Советую переходить на .NET — там ты все достанеш из RTTI.

Названия методов можна доставать у интерфейсов, порожденных от IInvoke (Кажется начиная с Delphi 6). Причем можна вытянуть информацию о параметрах.
Сделано борландовцами для поддержки SOAP.
См. IntfInfo.pas
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.