Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.048 c
3-1099920344
msguns
2004-11-08 16:25
2004.12.05
Обновление с подсчетом в Аксесе


1-1101107330
LOL
2004-11-22 10:08
2004.12.05
Печать


3-1099501529
Vova
2004-11-03 20:05
2004.12.05
Добавление записей в таблицу с несколькими одинаково заполнеными


14-1100612899
European
2004-11-16 16:48
2004.12.05
Таненбаум. Современные операционные системы


1-1101111515
BaDeVlad
2004-11-22 11:18
2004.12.05
Непечатаемые символы в RichEdit





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский