Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
1

Просмотр адреса метода

11.11.2014, 08:22. Показов 2320. Ответов 21
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
В процессе отладки возникла необходимость узнать адрес метода класса. Как это сделать? Т.е. как узнать чему равна Func в примере ниже?
C++
1
2
void (__closure *Func)(int a);
ShowMessage(Func); /// не компилит
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.11.2014, 08:22
Ответы с готовыми решениями:

Просмотр тела метода
Хотел бы узнать, как (можно ли вообще) посмотреть тело стандартного метода? public class...

CS0029 при присвоении переменной адреса метода
Добрый день! Делегат вызывается в неймспейс. Переменная создается в классе 2. Переменной...

Различия в выводе адреса метода класса через printf() и cout
Добрый день. Объясните пожалуйста, почему когда я пытаюсь вывести адрес метода класса с помощью...

Меняют ли элементы в vector свои адреса при вызове метода push_back?
Допустим я определил вектор и указатель на один из его элементов: vector< int > v( 10 ); int* p =...

21
1408 / 571 / 127
Регистрация: 31.10.2011
Сообщений: 1,960
11.11.2014, 09:20 2
C++
1
ShowMessage((int)&Func);
1
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
11.11.2014, 10:22  [ТС] 3
Нет. Мне нужен указатель на метод, а ваш вариант это указатель на указатель на метод.
0
1449 / 1121 / 347
Регистрация: 11.04.2011
Сообщений: 2,621
11.11.2014, 10:51 4
Цитата Сообщение от gumi250 Посмотреть сообщение
Мне нужен указатель на метод, а ваш вариант это указатель на указатель на метод
Ну так разыменуйте указатель на указатель:
C++
1
ShowMessage(*(int*)&Func);
А чем не устраивает просмотр адреса через дебаггер? Кстати, в дебаггере данный адрес представляется двумя числами. До второго числа, естественно, можно достучаться так:
C++
1
ShowMessage(*((int*)&Func + 1));
1
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32835 / 21172 / 8148
Регистрация: 22.10.2011
Сообщений: 36,432
Записей в блоге: 8
11.11.2014, 10:59 5
C++
1
2
    void* p = (void*&) Func;
    ShowMessage((int)p); // компилит, но такими вещами лучше не увлекаться...
1
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
11.11.2014, 15:13  [ТС] 6
Пробовал напрямую привести к void* и к int, но компилятор не дал, не понимаю почему.
Цитата Сообщение от kodv Посмотреть сообщение
А чем не устраивает просмотр адреса через дебаггер?
Ошибся вместо Func добавил в WatchList *Func, он естесвенно ничего не показал. Я так привык, что WatchList не показывает переменные что я даже не удивился и не заподозрил неладное.
Цитата Сообщение от kodv Посмотреть сообщение
Кстати, в дебаггере данный адрес представляется двумя числами. До второго числа, естественно, можно достучаться так
Вы же естественно понимаете, что метод это ф-ция со скрытым параметром. И адрес метода (как и любой другой адрес) это все таки 1 число, а второе число это адрес экземпляра класса.
0
Почетный модератор
Эксперт С++
5850 / 2861 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
11.11.2014, 15:21 7
Цитата Сообщение от gumi250 Посмотреть сообщение
Пробовал напрямую привести к void* и к int, но компилятор не дал, не понимаю почему
Мож к "int *", а не к "int"?
Именно кастованием, а не присваиванием не дал?
0
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
11.11.2014, 15:39  [ТС] 8
C++
1
2
3
void (__closure *Func)(int a);
ShowMessage((int)Func); /// не компилит
ShowMessage((int*)Func); /// не компилит
0
1408 / 571 / 127
Регистрация: 31.10.2011
Сообщений: 1,960
11.11.2014, 18:01 9
gumi250, обьясни, пожалуйста, что именно ты хочешь сделать, как и где обьявлена функция в классе и еще вот по теме.
Про __closure почти ничего нет, но много чего интересного
0
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
12.11.2014, 02:10  [ТС] 10
Есть компонент, скажем Button. У него событие OnMouseDown. Я динамически присваиваю OnMouseDown то один, то другой обработчик. И в какой то момент мне захотелось узнать какой из обработчиков установлен.
А вообще, т.к. WatchList не показывает все переменные, то я давно использую логирование. В очень сильно упрощенном варианте выглядет это примерно так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void PrintM(int a)
{
    ShowMessage(IntToStr(a)+"-int");
}
//---------------------------------------------------------------------------
void PrintM(void* a)
{
    ShowMessage(IntToStr((int)a)+"-void*");
}
////---------------------------------------------------------------------------
void PrintM(double a)
{
    ShowMessage(FloatToStr(a)+"-double");
}
////---------------------------------------------------------------------------
void PrintM(String a)
{
    ShowMessage(a+"-String");
}
//---------------------------------------------------------------------------
int i=3;
PrintM(i);
PrintM(&i);
int (__closure *Func1)(int a, int b);
PrintM(*(int*)&Func1); /// не красиво
А вот сделать для указателей на методы класса в том же русле я так понимаю не получится, т.к приходится шаманить с разыменованиями, что не очень красиво. Ну да ладно, благо это не частая задача.
0
1408 / 571 / 127
Регистрация: 31.10.2011
Сообщений: 1,960
12.11.2014, 02:25 11
WatchList показывает все переменные, которые находятся в области видимости ....
0
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
12.11.2014, 02:35  [ТС] 12
Цитата Сообщение от _Dimon_ Посмотреть сообщение
WatchList показывает все переменные, которые находятся в области видимости ....
Увы это не так
0
1408 / 571 / 127
Регистрация: 31.10.2011
Сообщений: 1,960
12.11.2014, 02:41 13
gumi250, ты написал в "упрощенном варианте". Скажи как надо, а то void PrintM(int a) и "его друзья" не очень вяжутся с OnMouseDown.
0
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
12.11.2014, 03:03  [ТС] 14
С OnMouseDown я уже решил и адрес на метод с шаманством переименования посмотрел.
Про логер (код с PrintM) это как бы вдогонку (т.к. был помянут WatchList). Т.е. все адреса на переменные и ф-ции компилятор легко приводит к void*, т.е. для них всегда вызываетя PrintM(void*). А вот написать функцию PrintM(void (__closure *Func)(void)) которая бы всегда вызывалась для любого указателя на метод класса, увы, я так понимаю, не получится. Поэтому придется писать некрасиво PrintM(*(int*)&Func1);
0
1449 / 1121 / 347
Регистрация: 11.04.2011
Сообщений: 2,621
12.11.2014, 08:23 15
Цитата Сообщение от gumi250 Посмотреть сообщение
Вы же естественно понимаете, что метод это ф-ция со скрытым параметром. И адрес метода (как и любой другой адрес) это все таки 1 число, а второе число это адрес экземпляра класса.
Я просто не обратил внимания на __closure. Если убрать __closure, то это будет не метод, а функция с одним единственным адресом.
Кстати, в дебаггере я смотрел адреса функций без Watch List'а; просто наводил указатель мыши на указатель на функцию, и во всплывающей подксказке отображалась нужная информация. Так работает дебаггер в BCB6. Сомневаюсь. что в более современных IDE ситуация с этим хуже.
0
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
12.11.2014, 08:30  [ТС] 16
Вроде раньше всплывала чего то, но я этим никогда не пользовался. Сейчас не всплывает, наверняка какую-нить галочку снял.
0
4043 / 2332 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
12.11.2014, 09:16 17
Цитата Сообщение от gumi250 Посмотреть сообщение
А вот написать функцию PrintM(void (__closure *Func)(void)) которая бы всегда вызывалась для любого указателя на метод класса, увы, я так понимаю, не получится. Поэтому придется писать некрасиво PrintM(*(int*)&Func1);
Все получится, если надо будет. Хотя, на мой взгляд, логирование оправдано разве что на отладке потоков и естественно без всяких ShowMessage()... остальное в отладчике посмотреть можно... ну, дык, каждый сам себе голова, так что черт с этим...

Вот пример синтаксиса номер раз:
Загрузка картинки в динамический TImage через поток

А вот номер двас, без всяких __closure:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template <class T>
class t_cursor_watcher
{
//...
    T *procs_provider;
//...
    void __fastcall( T::*base_class_proc )( ); // аналогичные указатели, но на функции-члены-класса
    bool __fastcall( T::*conditional_class_proc )( );
 
//...
    void __fastcall set_initials( int _base_interval, int _control_interval,
        RECT _margins, T *_procs_provider,
        void __fastcall( T:: *_base_class_proc )( ),
        int _base_check_mode = TCW_CM_EVERY_AND_CONTROL__NEGATIVE_CHECK,
        bool __fastcall( T:: *_conditional_class_proc )( ) = NULL,
        int _conditional_check_mode = TCW_CM_EVERY_AND_CONTROL__POSITIVE_CHECK );
C++
1
2
3
4
5
6
7
8
9
    if ( cursor_detected && base_control_check && cond_control_check ) {
        if ( use_class_procs ) {
            ( procs_provider->*base_class_proc )( );
        }
        else {
            base_proc( );
        }
        return;
    }
Само собой, класс так же городить не обязательно, можно обойтись одной шаблонной функцией
Дернул со старого проекта, так что на дизайн кода прошу внимания не обращать...
1
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
12.11.2014, 11:19  [ТС] 18
BRcr, Ваши примеры я чесно говоря не понял, но они навели меня на мысль, может это вы и имели в виду.
Вообщем вот так вроде работает:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void PrintM(int a)
{
    ShowMessage(IntToStr(a)+"-int");
}
void PrintM(void* a)
{
    ShowMessage(IntToStr((int)a)+"-void*");
}
void PrintM(double a)
{
    ShowMessage(FloatToStr(a)+"-double");
}
void PrintM(String a)
{
    ShowMessage(a+"-String");
}
template <class T> void PrintM(T (__closure *Func)(void))
{
    ShowMessage(IntToStr(*(int*)&Func) + "-met0");
};
template <class T, class T1> void PrintM(T (__closure *Func)(T1 a))
{
    ShowMessage(IntToStr(*(int*)&Func) + "-met1");
};
template <class T, class T1, class T2> void PrintM(T (__closure *Func)(T1 a, T2 b))
{
    ShowMessage(IntToStr(*(int*)&Func) + "-met2");
};
int i=3;
PrintM(i);
PrintM(&i);
int (__closure *Func1)(int a, int b);
PrintM(Func1);
Цитата Сообщение от BRcr Посмотреть сообщение
Хотя, на мой взгляд, логирование оправдано разве что на отладке потоков и естественно без всяких ShowMessage()... остальное в отладчике посмотреть можно...
Да уж конечно без ShowMessage(), это я для упрощения.
Не знаю, в каком отладчике можно все посмотреть, но у меня WatchList зачастую переменные не показывает и приходится их в логер выводить. Если в WatchList добавить штук 20 переменных, то пошаговая отладка начинает притормаживать. Конечно каждому свое, лично я без логера не могу.
0
4043 / 2332 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
12.11.2014, 11:26 19
Да, все вполне себе правильно.
0
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
12.11.2014, 11:30  [ТС] 20
BRcr, еще вопрос. У вас WatchList всегда показывает любые переменные которые вам нужны? Если он их не показывает что вы тогда делаете?
0
12.11.2014, 11:30
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.11.2014, 11:30
Помогаю со студенческими работами здесь

Невозможно передать ArrayList в аргументы метода без модификатора static у этого метода или метода main
Крч, хочу передать экземпляр класса ArrayList в метод, но ide говорит, что нельзя это сделать, пока...

Полиморфизм: вызов метода базового класса, переопределенного метода и нового метода
В базовом классе метод помечен как virtual. Насколько я понял из книги: override означает, что...

Как достать из телефонной книги адреса чатов, адреса проживания и сайты
Здравствуйте, как достать из телефонной книги адреса чатов, адреса проживания и сайты. телефоны и...

Почему при присваивании адреса массива не ставится знак '&' получения адреса
int main() { int a = { 2, 3 }; int* b; b = a; //Почему при присваивании адреса массива не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru