Текущий архив: 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.47 MB
Время: 0.034 c