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

Вниз

Уважаемые мастаки, подскажите как внутри функции узнать ее имя?   Найти похожие ветки 

 
novill   (2004-05-02 19:37) [0]

Вроде есть стандартные функции MethodbyAddress и AddressByMethod. А если нет адреса, но находишься в теле метода и надо узнать имя - как быть?

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


 
Ihor Osov'yak ©   (2004-05-02 20:28) [1]

имхо, странное желание..

но все же - можно попытаться определить начало метода по сигнатуре
55 8B EC 83 C4
что значит
push ebp
mov ebp, esp

естественно, если "желание" реализовать в виде функции - а это логично, придется анализировать адресс возврата в стеке..

.. имхо, вещь можно реализовать.. Но зачем?


 
Mim1 ©   (2004-05-02 20:40) [2]

novill   (02.05.04 19:37)

А название функции компилируется в готовую программу. IMHO нет, как и названия переменных.


 
Ihor Osov'yak ©   (2004-05-02 20:57) [3]

2 Mim1

1. Написать в редакторе среды IDE Delphi MethodName, выделить, нажать Ctrl+F1, прочитать, осознать.
2. Вспомнить, что речь велась все же о методах, а не о функциях.

2 novill

Об [1]. Если Вы не очень дружны с ассемблером, то в дополнение - упомянутая мною сигнатура - типичное начало кода и процедур, и методов. Но
если возьмете предложеный метод за основание - то все же проверьте это утверждение в разных ситуациях.. не исключаю, что вполне может быть несколько других push  перед push ebp.
.. Естественно, после получения адреса  начала метода - MethodName


 
novill   (2004-05-02 21:10) [4]


> .. имхо, вещь можно реализовать.. Но зачем?

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

> А название функции компилируется в готовую программу. IMHO
> нет, как и названия переменных.

С функциями согласен, но с методами объектов немного по-другому - имена остаются. Например: можно ввести имя метода в Edit"е, получить его адрес и выполнить!
Я посмотрел исходники методов MethodbyAddress и AddressByMethod, но там ассемблерные вставки, в которых я мало что понял.
А одна программка (Dunit) вообще в run-time простраивает список методов объекта. Но я их исходники совсем не понял.
Если кто-нибудь знает ассемблер, посморите, пожалуйста, там всего по 5-10 строчек!


 
Ihor Osov'yak ©   (2004-05-02 21:24) [5]

2 novill  

Лично бы я написал x100 вызовов типа AddToLog, чем реализовать, то, что предложено в [1]

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

И как вариант - что-то типа

 try
  Assert(false);
 except
   on E:Exception  do  begin
     tmpStr := E.message;

     AddToLog(GetNumberLineFromMsg(tmpStr));
   end;
 end;


конечно, это даст не названия методов, а строчки исходного текста - но все же..

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


 
Юрий Зотов ©   (2004-05-02 22:15) [6]

> novill   (02.05.04 21:10) [4]

> Я посмотрел исходники методов MethodbyAddress и
> AddressByMethod, но там ассемблерные вставки, в которых я мало
> что понял.

Вероятно, Вы имели в виду MethodAddress и MethodName. Там другой механизм и все достаточно просто.

Имена и адреса published-методов объектов (а MethodAddress и MethodName только для таких и работают) перечислены в специальной таблице методов, ссылка на которую сидит в VMT по заранее известному смещению. Строит эту таблицу компилятор. Зная класс (а класс - это вход в саму VMT), получаем адрес таблицы методов, а зная ее структуру, можно вытащить из нее имена и адреса всех перечисленных в ней методов. Это довольно просто, даже и без ассемблера.

MethodAddress и MethodName именно так и работают. Они сканируют таблицу методов и находят либо адрес метода по его имени, либо имя метода по его адресу (при этом учитывая, что метод может быть и унаследованным от предка).

Только вряд ли все это поможет для решения Вашей задачи. Конечно, Вы легко можете сделать все методы published и они попадут в таблицу методов. Но проблема в том, что, находясь внутри метода, Вы можете получить адрес текущей точки исполнения, а Вам нужен не он, а адрес точки входа в сам метод. Можно, как сказал Игорь, искать его по сигнатуре (см. [1]), но, как он же и заметил, нет уверенности в том, что такое решение будет работать всегда и на 100%.

Поэтому присмотритесь к [5]. Assert дает в тексте сообщения имя модуля и номер строки. Выделить их несложно, а обработчик можно сделать централизованным (Application.OnException). И останется только в нужных точках вызывать Assert.



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

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

Наверх




Память: 0.49 MB
Время: 0.027 c
9-1072024759
dRake
2003-12-21 19:39
2004.05.16
Рендер на текстуру под PowerDraw!


6-1080543570
Layner
2004-03-29 10:59
2004.05.16
UDP посылки. Возможно ли получить UDP сообщение от Win2000


8-1077358690
Кащей[БЦ]
2004-02-21 13:18
2004.05.16
Несколько вопросов по реализации плэйера на основе Bass 2.0


4-1080239386
Константин
2004-03-25 21:29
2004.05.16
Как запустить из процесса другую программу?


1-1083674882
Girder
2004-05-04 16:48
2004.05.16
Как быстро удалить указатель из списка