Форум: "Основная";
Текущий архив: 2004.12.05;
Скачать: [xml.tar.bz2];
ВнизПерекрытие невиртуальный процедуры? Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.034 c