виртуальные методы
Модератор: Модераторы
виртуальные методы
Помогите, плиз, разобраться, как получить адрес виртуального метода в таблице VMT. Как в Делфи не получается, выдает ошибку. Free Pascal только осваиваю
меня всегда интересовали проблемы типа "хакаем язык", можно ли узнать для чего (для каких целей) знать адрес виртуального метода?!
мне всегда хватало "не знать" адреса.
мне всегда хватало "не знать" адреса.
Код: Выделить всё
TMyMethod = procedure (...params... ) of object;
TMyObject = class (...)
procedure AMethod(...params...); virtual;
end;
var
p : TMyMethod;
begin
p:=m.AMethod;
...
p(...params...)
пробую написать для free pascal подобие Delphi VCL компонентов, основываясь на WINAPI. Функцию обработки оконных сообщений объявил как virtual, чтобы можно было наследникам ее переопределить. В Делфях адрес получить можно с помощью ассемблера, но в free pascal таблица VMT строится иначе, и я не могу понять как к ней грамотно обратиться.
P.S. А за ответ спасибо, но думаю что не сработает. Хотя попробую
P.S. А за ответ спасибо, но думаю что не сработает. Хотя попробую
Не проще ли функцию обработки оконных сообщений сделать невиртуальной, а из нее вызывать виртуальную, которую уже можно переопределить?
пробовал, но у меня не получается. Может что-то не то делаю, хотя в Делфи получается двумя способами
giao писал(а):пробовал, но у меня не получается. Может что-то не то делаю, хотя в Делфи получается двумя способами
а не проще сделать как это делает Lazarus?
всё без хаков.
На окно навешивается (через SetWindowLong, он 64-bitный для x64) указатель на объект. При обработке сообщения, этот объект получается и вызывается его virtual метод.
Всё легально и без извращений. И кроме того, кроссплатформенно!
Или можно присоединить к дескриптору окна свойство (SetProp/GetProp), имя которого будет содержать дескриптор атома, например, с ID процеса, а значение - указатель на объект. Это еще удобно тем, что всегда можно найти по дескриптору окна соответствующий объект, а не только наоборот. Так, кажется, сделано в Delphi.
Тем не менее, способ, указанный уважаемым скалогрызом в предыдущем посте - через SetWindowLong (индекс GWL_UserData), - работает быстрее и является, если можно так выразиться, более технологичным и поэтому чаще используемым.
Если диспетчеризация оконных сообщений пишется на встроенном ассемблере, то стОит присмотреться к директиве VMT_OFFSET, но я не уверен, что она реализована для всех процессоров (для ARM точно не работает).
Тем не менее, способ, указанный уважаемым скалогрызом в предыдущем посте - через SetWindowLong (индекс GWL_UserData), - работает быстрее и является, если можно так выразиться, более технологичным и поэтому чаще используемым.
Если диспетчеризация оконных сообщений пишется на встроенном ассемблере, то стОит присмотреться к директиве VMT_OFFSET, но я не уверен, что она реализована для всех процессоров (для ARM точно не работает).
