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

Вниз

Определение адреса метода изнутри   Найти похожие ветки 

 
Alex_Ne   (2007-11-12 15:26) [0]

Добрый день! Каждый метод имеет ссылку на собственный обект (переменная Self). А что делать, если код метода должен получить адрес или имя самого метода? Можно ли его извлечь
откуда-либо.
 Вбивать для каждого метода код типа

 procedure DestСomp.AnyoneMethod(Sender: TObject);
 var Code : pointer;
 begin  
 Code := MethodAddress("AnyoneMethod");
 или
 Code := @AnyoneMethod;
 ............................................
 end;

как-то представляется не очень красивым и правильным. Хотелось бы иметь универсальный подход. Т.е. последовательность операторов, не требующую изменений и позволяющую внутри метода получить его адрес или имя.  
Но облазив Help не нашел ничего подходящего. Может кто сталкивался с подобной проблемой?
Заранее спасибо.


 
Сергей М. ©   (2007-11-12 15:32) [1]


> Хотелось бы иметь универсальный подход


Нет такого и быть не может.
Да и за каким лешим это может понадобиться - тоже ба-а-альшой вопрос


 
Alex_Ne   (2007-11-12 15:46) [2]


> Да и за каким лешим это может понадобиться - тоже ба-а-альшой
> вопрос


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


 
Сергей М. ©   (2007-11-12 15:50) [3]


> нужно фиксировать каким-то образом вызовы определенных в
> базовом классе и переопределяемых (override) в потомках
> методов


Что значит "фиксировать" ? Протоколировать что ли ?
И зачем ? В целях отладки или ?


 
Alex_Ne   (2007-11-12 16:52) [4]

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

Долго я сэтим парился, потом стал паковать объект и отсылать клиенту.
Вышло оч хорошо. Экотомится масса времени разработчика и программы.
Остается унифицировать как-то вызов методов и совсем все было бы в ажуре.

Для этого и потребовалось решать означенную задачу.


 
Сергей М. ©   (2007-11-12 16:58) [5]


> С целью передачи клиенту по сетке


Все это делается средствами IDispath-интерфейсов и их наследников.
И при этом нет никакой нужды держать библ-ку типов на стороне контроллера.


 
oxffff ©   (2007-11-12 17:07) [6]


> Сергей М. ©   (12.11.07 15:32) [1]
>
> > Хотелось бы иметь универсальный подход
>
>
> Нет такого и быть не может.
> Да и за каким лешим это может понадобиться - тоже ба-а-альшой
> вопрос


На здоровье.

procedure TForm1.abc;
var a,b:integer;
   methodAdress:pointer;
begin
asm
mov eax,[ebp+4];
mov ecx,[eax-4];
add eax,ecx;
mov methodAdress,eax;
end;
end;


 
oxffff ©   (2007-11-12 17:08) [7]


> oxffff ©   (12.11.07 17:07) [6]


Если нет стекового фрейма, то и это можно решить.


 
Сергей М. ©   (2007-11-12 17:12) [8]


> Если нет стекового фрейма, то и это можно решить


Вот и попробуй)
Причем на все случаи жизни)


 
oxffff ©   (2007-11-12 17:20) [9]


> Сергей М. ©   (12.11.07 17:12) [8]


Во всяком случае я не говорю, что это невозможно.

А вы эту поставьте галочку, stack frame и будет вам счастье.


 
Alex_Ne   (2007-11-12 17:23) [10]

> oxffff

Это работает!!!
Огромное спасибо oxffff,
Когда смотрел исходники в System возникало подозрение, что без ассемблера не обойтись - чтож, теперь будем разбираться.
Все-таки странно, что Borland не предусмотрели штатных механизмов доступа к эт им адресам.


 
Сергей М. ©   (2007-11-12 17:25) [11]


> я не говорю, что это невозможно


Конечно невозможно)
Никто не понуждает держать адрес возврата в стеке.


> оставьте галочку, stack frame и будет вам счастье


Мне оно нафих не нужно.
К тому же это частный случай)


 
Сергей М. ©   (2007-11-12 17:26) [12]


> Borland не предусмотрели штатных механизмов доступа к эт
> им адресам


Зато Борланд предоставил вполне приличный отладчик, умение пользоваться которым практически сводит на нет небходимость в подобного рода выкрутасах.


 
Alex_Ne   (2007-11-12 17:33) [13]


> Все это делается средствами IDispath-интерфейсов и их наследников.
>
> И при этом нет никакой нужды держать библ-ку типов на стороне
> контроллера.


Разумеется. Вот я и делаю максимально простой IDispath-интерфейс про который затем можно забыть и сосредоточиться на функциональных компонентах.
Не претендую на универсальность, но для моего проекта такой подход до сих пор был более эфективен чем стандартные диспинтерфейсы.


 
oxffff ©   (2007-11-12 17:36) [14]


> Сергей М. ©   (12.11.07 17:25) [11]


>Никто не понуждает держать адрес возврата в стеке.

Ого. А тогда ret узнает об этом. Если работает со стеком.
Извольте прочитать работу RET. :)

Вы всегда в своем звездном репертуаре.
За сим откланиваюсь.


 
oxffff ©   (2007-11-12 17:42) [15]


> Alex_Ne   (12.11.07 15:46) [2]


Почитай мой блог.

http://santonov.blogspot.com/

Может, что пригодиться.


 
oxffff ©   (2007-11-12 18:00) [16]


> Может, что пригодиться.


Мне реально нужно другие книги читать. Начать с букваря.

пригодится


 
Alex_Ne   (2007-11-12 18:27) [17]


> Почитай мой блог.
> http://santonov.blogspot.com/
> Может, что пригодиться.


Спасибо за ссылку. Тем более что я не силен в ассемблере,
а разбираться все равно нужно - назрела необходимость.


 
Сергей М. ©   (2007-11-13 08:14) [18]


> А тогда ret узнает об этом


Организовать возврат в нужную точку можно и без RET.


> Извольте прочитать работу RET


Прямо сейчас бегу вприпрыжку)

И тебе настоятельно рекомендую ознакомиться с выкрутасами в передаче параметров и управления между подпрограммами, фигурирующей, к примеру, в алладиновой секции .protect  - код, генерируемый компиляторами от Борланда, раем покажется)


 
Сергей М. ©   (2007-11-13 08:17) [19]


> Alex_Ne   (12.11.07 17:33) [13]


> стандартные диспинтерфейсы


Какие такие "стандартные" ?

Тебе чего надо-то ?
По запросу контроллера вернуть ему список имен диспинтерфейсных методов с целью последующих вызовов контроллером этих методов ?


 
oxffff ©   (2007-11-13 08:33) [20]


> Сергей М. ©   (13.11.07 08:14) [18]


Этот форум про методы защиты?
Или про устройство виртуальных машин?


 
oxffff ©   (2007-11-13 08:45) [21]


> Сергей М. ©   (13.11.07 08:14) [18]
>
> > А тогда ret узнает об этом
>
>
> Организовать возврат в нужную точку можно и без RET.


Ого. А что есть другие способы (средствами языка) возврата из процедуры в Delphi?


 
oxffff ©   (2007-11-13 08:46) [22]


> Ого. А что есть другие способы (средствами языка) возврата
> из процедуры в Delphi?


Исключения в расчет не брать.


 
Alex_Ne   (2007-11-13 12:46) [23]

to Сергей М. ©   (13.11.07 08:17) [19]


> Какие такие "стандартные" ?

Т.е. создаваемые и используемые ровно таким образом, как это предусматривает DCOM - универсальный подход не бывает оптимальным
для всех случаев жизни.


> Тебе чего надо-то ?

Goto  (12.11.07 15:26)
http://delphimaster.net/view/1-1194870400/


> По запросу контроллера вернуть ему список имен диспинтерфейсных
> методов с целью последующих вызовов контроллером этих методов
> ?

Ответ на поставленный вопрос я уже получил [6]. Прочее офтоп.
Нет необходимости строить фантастические предположения -
если действительно интересны подробности - пиши на мыло.


 
oxffff ©   (2007-11-13 12:56) [24]


> Ответ на поставленный вопрос я уже получил [6].


Этот способ действует для методов direct call методов со стековым фреймом.
Для indirect методов (виртуальных методов) он не сработает.
Для этого его нужно слегка модифицировать. Но сделать можно.


 
Сергей М. ©   (2007-11-13 13:07) [25]


> универсальный подход не бывает оптимальным


А что тебя заклинило на DCOM ?

Используй TSocketConnection и адаптированный под свои нужды BSS, тогда - скажу тебе по великому секрету - не понадобится не только библ-ка типов, но и вообще какие-либо следы в реестрах, ни на стороне сервера ни на стороне контроллера. Плясать для этого нужно от TComObjectFactory.Instancing = ciInternal, тогда BSS будет создавать объект твоего app-сервера "на лету", безо всяких привязок к реестру. Контроллер же обращается к app-серверу через его диспинтерфейс, что также не требует привязки к реестру и библ-ке типов.


 
Сергей М. ©   (2007-11-13 13:13) [26]

И вообще совершенно непонятно зачем апп-серверу знать имена методов дельфийских объектов


 
Сергей М. ©   (2007-11-13 13:20) [27]


> имена методов дельфийских объектов


Точнее не имена , а адреса точек входа в эти методы.


 
Сергей М. ©   (2007-11-13 13:24) [28]


> Остается унифицировать как-то вызов методов и совсем все
> было бы в ажуре.
>
> Для этого и потребовалось решать означенную задачу


Невегной дорогой идете, товагищ, агхиневегной)

Засим откланиваюсь.


 
Alex_Ne   (2007-11-14 10:17) [29]


> А что тебя заклинило на DCOM ?
>
> Используй TSocketConnection и адаптированный под свои нужды
> BSS, тогда - скажу тебе по великому секрету - не понадобится
> не только библ-ка типов, но и вообще какие-либо следы в
> реестрах, ни на стороне сервера ни на стороне контроллера.
>

...............

На самом деле от DCOM я давно отказался в пользу TSocketConnection по означенным причинам и не только. Но сути это не меняет, а букоф меньше...


 
Сергей М. ©   (2007-11-14 10:36) [30]


> На самом деле от DCOM я давно отказался в пользу TSocketConnection


Малацца.
Осталось заточить BSS под свои нужды с учетом ciInternal.


 
Alex_Ne   (2007-11-14 10:41) [31]


> Этот способ действует для методов direct call методов со
> стековым фреймом.
> Для indirect методов (виртуальных методов) он не сработает.
>  
> Для этого его нужно слегка модифицировать. Но сделать можно.
>


Методы всюду динамические. Специально попробовал объявить метод как виртуальный - все равно сработало (или  я что-то не правильно понял?).
 TMeth = class(TComponent)
 published
   procedure abc;virtual;
 end;

 TChMeth = class(TMeth)
 published
   procedure abc;override;
 end;


 
Alex_Ne   (2007-11-14 10:53) [32]


> скажу тебе по великому секрету - не понадобится не только
> библ-ка типов, но и вообще какие-либо следы в реестрах,
> ни на стороне сервера ни на стороне контроллера.


И как-же реализуется загрузка сервера по запросу клиента, если в
реестре на стороне сервера никаких следов?


 
Сергей М. ©   (2007-11-14 11:06) [33]

Оч просто - TComObject.CreateFromFactory


 
Alex_Ne   (2007-11-14 11:09) [34]


> BSS будет создавать объект твоего app-сервера "на лету",
>  безо всяких привязок к реестру

А если их (арр-серверов) сдесяток на одном компе и состав может
меняться, в зависимости от того, какое оборудование куда
подключается? Что, каждый раз BSS затачивать?


 
Сергей М. ©   (2007-11-14 11:19) [35]


> А если их (арр-серверов) сдесяток на одном компе и состав
> может
> меняться, в зависимости от того, какое оборудование куда
> подключается?


Да на здоровье. Хоть миллион)

Тебя же не смущает наличие в системе огромной кучи dll/exe с фабриками классов ?)


> Что, каждый раз BSS затачивать?


BSS затачивается один раз. Но перед этим затачиваются голова + руки.


 
Alex_Ne   (2007-11-14 11:32) [36]

.........

> Но перед этим затачиваются голова + руки.


Воистину универсальная рекомендация. Продолжать дискуссию не вижу смысла, ибо все остальное частноси, не заслуживающие внимания.


 
Сергей М. ©   (2007-11-14 11:32) [37]

Аминь.



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

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

Наверх




Память: 0.57 MB
Время: 0.022 c
1-1194870400
Alex_Ne
2007-11-12 15:26
2008.06.22
Определение адреса метода изнутри


2-1211821567
Рустам Ганеев
2008-05-26 21:06
2008.06.22
DBgrid, установка курсора в нужную позицию


3-1200479843
Данила
2008-01-16 13:37
2008.06.22
Еще раз я...


2-1211957443
Ega23
2008-05-28 10:50
2008.06.22
Надо ли ставить override?


2-1211994788
assassin8899
2008-05-28 21:13
2008.06.22
Edit