Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Объявление функции используя пользовательский тип (typedef)  (Прочитано 17773 раз)
0 Пользователей и 1 Гость смотрят эту тему.
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« : 05-05-2006 07:01 » 

Название может и не самое удачное, но тем не менее.
Алексей 1153 заинтресовался вопросом, а задать не может, т.к. доступа к форуму у него нет.
И так, дальнеййшие слова его:

к примеру имеется тип функции HOOKPROC, он определён как
typedef LRESULT (CALLBACK* HOOKPROC)(int code, WPARAM wParam, LPARAM lParam);

как объявить процедуру этого типа, используя только HOOKPROC ?
то есть написать что-то вроде
Код:
     //прототип в объявлении класса CMyClass
     HOOKPROC myF();
     //реализация
     HOOKPROC CMyClass::myF()
     {
     }

при этом подразумевая
Код:
     //прототип в объявлении класса CMyClass
     LRESULT CALLBACK myF(int code, WPARAM wParam, LPARAM lParam);

     //реализация
     LRESULT CALLBACK CMyClass::myF(int code, WPARAM wParam, LPARAM lParam)
     {
     }
Вопрос стоит отметить интересный.
Записан

ещё один вопрос ...
Chaa
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 05-05-2006 07:12 » 

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

Интересно узнать, для чего?
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 05-05-2006 07:26 » 

Ему это для удобства.
И вот он спрашивает
Цитата
а если я тип поменяю - это лазить везде менять?
Записан

ещё один вопрос ...
Chaa
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 05-05-2006 07:58 » 

Да, менять. Менять в любом случае придется код вызова этих функций.
Можно попробовать использовать функторы:
Код:
class MyFunctorBase
{
public:
    virtual LRESULT operator()(int code, WPARAM wParam, LPARAM lParam);
};
class MyFunctor : public MyFunctorBase
{
public:
    LRESULT operator()(int code, WPARAM wParam, LPARAM lParam)
    {
        ...
        return 0;
    }
};
Работа с ним:
Код:
DoSomething(MyFunctorBase& f)
{
    f(0, 0, 0);
}
Это я в кратце описал смысл, а вообще все сложнее и можно сделать значительно интереснее с использованием шаблонов.
Но об этом нужно читать Александреску "Современное проектирование на C++".
https://club.shelek.ru/download.php?id=287

Хотя все равно менять все... Улыбаюсь
« Последнее редактирование: 05-05-2006 08:01 от Chaa » Записан
Chaa
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 05-05-2006 09:55 » 

Есть одно решение проблемы - макросы.
Код:
#define MY_FUNCTION(name) LRESULT CALLBACK \
    name(int code, WPARAM wParam, LPARAM)
Код:
MY_FUNCTION(f1)
{
}
Но у макросов свои проблемы - сложнее искать ошибки, да и ошибиться очень просто, трудности с отладкой...
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 05-05-2006 10:50 » 

Макросы он не хочет. Макросы я  и сам предложил Ага.
Записан

ещё один вопрос ...
Scorp__)
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 05-05-2006 12:12 » 

Погодите-погодите, а разве можно CallBack процедуру, да еще и стандартную API-шную включить в класс, как метод?

Дело в том, что такие процедуры имеют строго указанную сигнатуру, если она будет отличаться, то использовать их не получится. А компилятор, когда будет транслировать класс даст на деле такую сигнатуру Callback  функции:

Код:
LRESULT CALLBACK myF(CMyClass* this, int code, WPARAM wParam, LPARAM lParam);

То есть WinAPI больше не примет эту функцию за "свою".
Если все-таки можно так сделать, расскажите, пожалуйста, как. Очень интересно.
Записан

- А Вы сами-то верите в привидения?
- Конечно, нет, - ответил лектор и медленно растаял в воздухе.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #7 : 05-05-2006 12:36 » 

Scorp__), Можно сделать, если
1. такую процедуру объявить статичной. Только останется одна проблема. Как потом узнать this  соответствуюшего класса.
2. Функции друзья
3. Где то на форуме видел, там перед функцией-членом класса предлагали делать ассемблерные вставки. и давать ссулку на данную ассемблерную вставку.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 05-05-2006 15:54 » 

люди, да ну что вы привязались к HOOKPROC Улыбаюсь Это я для примера.

пускай надо
typedef int(*F)(int nX);

Chaa, дефайны - вроде это единственное пока решение Улыбаюсь

я сделал так

Код:
#define	MY_F_pars	int nX
#define MY_F_ret int
typedef MY_F_ret (*pMY_F)(MY_F_pars);
#define MY_F(name) MY_F_ret name(MY_F_pars)

//MY_F(f) - тип функции f
//pMY_F pf- указатель на функцию f

например

//прототип
class C
{
static MY_F(f);
};

//реализация
MY_F(C::f)
{
//указатель
pMY_F pf;

pf=f;
pf(1);

return 0;
}
Записан

Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 06-05-2006 05:22 » 

Да вроде бы проблем не должно возникать.  Здесь была моя ладья...
Вот пример:
/////////////////////////////////
#include <stdio.h>

typedef int (*PROC)(char *, int);

int my_print(char *lp, int a);

int main(void)
{
   PROC lpProc;
   int i;

   lpProc = my_print;

   i = (*lpProc)("Test",100);
   printf("%d\n",i);

   return 0;
}

int my_print(char *lp, int a)
{
   return printf("%s = %d\n",lp,a);
}
///////////////////////////////////////
И в классах тот же принцип используется.

Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 06-05-2006 08:38 » 

Serg79, дык!

а вот это
int my_print(char *lp, int a);
- определи ка при помощи PROC ? Ага
Записан

Scorp__)
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 09-05-2006 21:37 » 

Finch, такие способы я знаю Улыбаюсь Но как раз в передаче this и проблема, для HOOKPROC этого сделать нельзя, нет там параметра соответствующего. Но в общем, ладно, дискуссия все равно оказалась в стороне от этого вопроса Улыбаюсь
Записан

- А Вы сами-то верите в привидения?
- Конечно, нет, - ответил лектор и медленно растаял в воздухе.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #12 : 09-05-2006 21:50 » 

Scorp__), Я лично стараюсь в Dll классы не сувать. Но с другой стороны. Я не думаю, что ты будеш использовать сразу несколько хуков на клавиатуру, поэтому можно смело использовать схему чуть доработанного Синглетона.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #13 : 10-05-2006 04:40 » 

Я кстати не разу не встречал, чтобы с помошью typedef пытались объявлять прототипы или заголовки функций, да я думаю что это и некчему. Обычно typedef используют для определения новых имен уже сушествующих типов данных, а новый все равно не получится создать.  Здесь была моя ладья...
Записан
Anchorite
Гость
« Ответ #14 : 10-05-2006 05:38 » 

Ребята, вы ничего не путаете?

Цитата
к примеру имеется тип функции HOOKPROC, он определён как
typedef LRESULT (CALLBACK* HOOKPROC)(int code, WPARAM wParam, LPARAM lParam);

Это определение типа, являющегося УКАЗАТЕЛЕМ на функцию, но не самой функцией.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 10-05-2006 08:34 » 

Anchorite, не путаем, это для примера было. Вопрос не в этом Улыбаюсь (см пост №8)
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines