Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.12.05;
Скачать: CL | DM;

Вниз

Перекрытие невиртуальный процедуры?   Найти похожие ветки 

 
Erik1 ©   (2004-11-24 11:39) [0]

Я хочу в своем наследнике перекрыть невиртуальную процедуру, помню что для этого были в JCL(RX) спецальные функции для работы с VMT. Напомните мне как это делается. Функция начиналась на Virtual... Смотрел примеры еще в RX, но прошло много времени и немогу вспомнить где это место.


 
PVOzerski ©   (2004-11-24 11:54) [1]

Но ведь невиртуальной процедуры просто нет в VMT...


 
Erik1 ©   (2004-11-24 12:01) [2]

Нашол старые функции FindVirtualMethodIndex GetVirtualMethodAddress SetVirtualMethodAddress. Есть еще какието варианты?
type
 TIdAttachment = class(TIdMessagePart) //исходный
 public
   //это надо заменить
   procedure Encode(ADest: TStream);
 end;

 TIdAttachmentEx = class(TIdAttachment) //мой класс
 public
   procedure Encode(ADest: TStream); reintroduce;
   property Body: string read FBody write SetBody;
 end;


 
Erik1 ©   (2004-11-24 12:02) [3]

Да действительно к VMT это отношения неимеет, все работает через WinApi VirtualProtect.


 
KSergey ©   (2004-11-24 12:32) [4]

> [3] Erik1 ©   (24.11.04 12:02)
> все работает
> через WinApi VirtualProtect.

Чего??!

type
TIdAttachment = class(TIdMessagePart) //исходный
public
  //это надо заменить
  procedure Encode(ADest: TStream);
end;

TIdAttachmentEx = class(TIdAttachment) //мой класс
public
  procedure Encode(ADest: TStream); override;
  property Body: string read FBody write SetBody;
end;


Хотя может и ваш код проедет.
Но "аменить" нормально не получится. Все, кто дубут пользоваться вашим классом и наследниками - будут попадать в код TIdAttachmentEx.Encode. Внутри же TIdAttachment будет вызываться TIdAttachment.Encode и ничего с этим поделать нельзя.
Авторы не предумастривали перекрытие эгото метода. Возможно, ест какой-либ одработчик или другой метод, который по сути реализует функциональность и предназначен для перекрытия в потомках.


 
Alexander Panov ©   (2004-11-24 12:48) [5]

KSergey ©   (24.11.04 12:32) [4]
procedure Encode(ADest: TStream); override;


Разве override используется для перекрытия статических методов?


 
Erik1 ©   (2004-11-24 12:58) [6]

После некоторых эксперементов и размышлений понял, что функции из модуля JvHook (FindVirtual...) работают только с виртуальными методами. Кто может помочь и с кодом для замены статического метода?

function SetVirtualMethodAddress(AClass: TClass; AIndex: Integer;
 NewAddress: Pointer): Pointer;
const
 PageSize = SizeOf(Pointer);
var
 Table: PPointer;
 SaveFlag: DWORD;
begin
 Table := PPointer(AClass);
 Inc(Table, AIndex - 1);
 Result := Table^;
 if VirtualProtect(Table, PageSize, PAGE_EXECUTE_READWRITE, @SaveFlag) then
 try
   Table^ := NewAddress;
 finally
   VirtualProtect(Table, PageSize, SaveFlag, @SaveFlag);
 end;
end;

function GetVirtualMethodAddress(AClass: TClass; AIndex: Integer): Pointer;
var
 Table: PPointer;
begin
 Table := PPointer(AClass);
 Inc(Table, AIndex - 1);
 Result := Table^;
end;


 
Alexander Panov ©   (2004-11-24 13:29) [7]

А такой вариант почему не устраивает?


  T1=class
  public
    procedure Test1;<br>
  end;<br>
<br>
  T2=class(t1)<br>
  public
    procedure Test1;<br>
  end;<br>



procedure T1.Test1;<br>
begin
  ShowMessage("1");<br>
end;<br>
<br>
procedure T2.Test1;<br>
begin
  ShowMessage("2");<br>
end;<br>


 
Плохиш ©   (2004-11-24 13:29) [8]


> Erik1

IMHO, адреса невиртуальных методов расчитываются в момент компиляции. Поэтому при перекрытии будет вызываться метод в зависимости от типа переменной или приведения типов.
Посмотри в справке по статическим методам (Static methods?)


 
Erik1 ©   (2004-11-24 13:30) [9]

Мне нужно Attachment отпрвить к письму, а информацию брать их String. В Indy сделано только из файла.


 
Digitman ©   (2004-11-24 13:33) [10]


> Erik1


> Кто может помочь и с кодом для замены статического метода?


ну решил ты обойти на повороте компилятор, ну установил нужный атрибут станицы для записи в нее (кстати, непонятно, для чего нужен EXECUTE-флаг - просто щоб було ?), ну записал в какую-то там таблицу какой-то там новый адрес ... толку-то ? ... любые обращения к стат.методу компилятор сводит к генерации во всех местах, где есть видит это обращение, к инструкции

call непосредственный_адрес

что с этим-то фактом делать будешь ?


 
Плохиш ©   (2004-11-24 13:34) [11]


> Erik1 ©   (24.11.04 13:30) [9]
> Мне нужно Attachment отпрвить к письму, а информацию брать
> их String. В Indy сделано только из файла.

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


 
Erik1 ©   (2004-11-24 13:34) [12]

to Alexander Panov
Потому что вызываю не я а Indy. Там стоит TIdAttachment(AMsg.MessageParts[i]).Encode(LDestStream); И вызывается старый метод.

to Плохиш
Мне должно стать от этого легче? Понятно, что свой я могу вызвать только отредактировав адрес метода в готовом экземпляре объекта, но как это сделать?


 
Digitman ©   (2004-11-24 13:37) [13]


> Erik1 ©   (24.11.04 13:30) [9]
> Мне нужно Attachment отпрвить к письму, а информацию брать
> их String. В Indy сделано только из файла.


о-о-о ..

точно не ту траву закурил ты ..

Инди пока еще поставляется с исх.текстами ... достаточно добавить к Attachment-классу метод а-ля LoadFromString(), пересобрать Инди-пакет - и всех делов !... а ты в такие дебри ринулся)


 
Плохиш ©   (2004-11-24 13:38) [14]


> Erik1 ©   (24.11.04 13:34) [12]
> Понятно, что свой я могу
> вызвать только отредактировав адрес метода в готовом экземпляре
> объекта, но как это сделать?

никак


 
Erik1 ©   (2004-11-24 14:55) [15]

To Digitman
Я раньше так и делал, надоело каждый раз ругань на несовподение версий слушать и хотел решить проблему. Вобщем сделал в исходниках метод виртуальным. Надо только назабыть в следующих версиях исправлять.

Всем спасибо.



Страницы: 1 вся ветка

Текущий архив: 2004.12.05;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.051 c
3-1099815997
klerk
2004-11-07 11:26
2004.12.05
Update БД


1-1100889661
markers
2004-11-19 21:41
2004.12.05
Как вызвать процедуру находящуюся в переменной.


9-1089441229
OSokin
2004-07-10 10:33
2004.12.05
Создание логических игр


1-1100693333
denis24
2004-11-17 15:08
2004.12.05
разбивка числа на разряды


14-1100375381
Soft
2004-11-13 22:49
2004.12.05
Сектор Газа.