как передать в функцию указатель на метод класса
От: ArickS  
Дата: 19.10.02 11:29
Оценка:
Господа программисты ответьте пожалуйста как передать в функцию указатель на метод класса?
Т.е. есть у меня метод
VOID CALLBACK TimerDictionary::TimerProc(HWND hwnd, UINT uMsg, unsigned int idEvent, DWORD dwTime)
надо передать его в функцию :

VOID TimerDictionary::SetTimer()
{
idTimer = SetTimer(0,0,TimeDelay,&TimerProc);
//здесь возникает ошибка
}
Re: как передать в функцию указатель на метод класса
От: Kaa Украина http://blog.meta.ua/users/kaa/
Дата: 19.10.02 12:29
Оценка:
Здравствуйте ArickS, Вы писали:

class TimerDictionary
{
...
  static VOID CALLBACK TimerProc(...); 
};


Функция должна быть либо глобальной, либо статическим членом класса.
Алексей Кирдин
Re: как передать в функцию указатель на метод класса
От: Dr_Sh0ck Беларусь  
Дата: 19.10.02 14:45
Оценка:
Здравствуйте ArickS, Вы писали:

AS>Господа программисты ответьте пожалуйста как передать в функцию указатель на метод класса?

AS>Т.е. есть у меня метод
AS>VOID CALLBACK TimerDictionary::TimerProc(HWND hwnd, UINT uMsg, unsigned int idEvent, DWORD dwTime)
AS>надо передать его в функцию :

AS>VOID TimerDictionary::SetTimer()

AS>{
AS> idTimer = SetTimer(0,0,TimeDelay,&TimerProc);
AS>//здесь возникает ошибка
AS>}

Поищи по форуму.
Do not fake yourself ;)
ICQ#: 198114726
Re: как передать в функцию указатель на метод класса
От: RS Земля ICQ: 148844272
Дата: 21.10.02 11:11
Оценка:
Здравствуйте ArickS, Вы писали:

AS>Господа программисты ответьте пожалуйста как передать в функцию указатель на метод класса?


Вот недавно увидел:
http://rsdn.ru/forum/Message.aspx?mid=108689
Автор: dupamid
Дата: 02.10.02


Хотя сам предпочитаю static.
Re: Есть тут один хакер... :)))
От: jazzer Россия Skype: enerjazzer
Дата: 21.10.02 11:30
Оценка:
Здравствуйте ArickS, Вы писали:

Можно поискать слово thunk

Или заглянуть в сорцы ATL
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: как передать в функцию указатель на метод класса
От: kmn Украина  
Дата: 21.10.02 11:36
Оценка: 3 (1)
Здравствуйте ArickS, Вы писали:

AS>Господа программисты ответьте пожалуйста как передать в функцию указатель на метод класса?

AS>Т.е. есть у меня метод
AS>VOID CALLBACK TimerDictionary::MyTimerProc(HWND hwnd, UINT uMsg, unsigned int idEvent, DWORD dwTime)
AS>надо передать его в функцию :

AS>VOID TimerDictionary::SetTimer()

AS>{
AS> idTimer = SetTimer(0,0,TimeDelay,&TimerProc);
AS>//здесь возникает ошибка
AS>}

class TimerDictionary
{
protected:
static VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
TimerDictionary * pThis = (TimerDictionary*)idEvent;
pThis->OnTimer();
}

public:
void SetTimer()
{
idTimer = ::SetTimer(NULL, (UINT)this, TimeDelay, TimerProc);
}

void OnTimer()
{

}
};



..
idTimer = SetTimer(0,0,TimeDelay, MyTimerProc);
..
Re[2]: как передать в функцию указатель на метод класса
От: SVV Беларусь  
Дата: 22.10.02 09:56
Оценка:
Здравствуйте Kaa, Вы писали:

Kaa>Здравствуйте ArickS, Вы писали:


Kaa>
Kaa>class TimerDictionary
Kaa>{
Kaa>...
Kaa>  static VOID CALLBACK TimerProc(...); 
Kaa>};
Kaa>


Kaa>Функция должна быть либо глобальной, либо статическим членом класса.

Что физически одно и тоже. А тербование это из-за того, что для вызова ф-ции-члена класса, недостаточно знать ее адрес — нужно знать еще и адрес объекта, который она обслуживает.
Re[2]: как передать в функцию указатель на метод класса
От: SVV Беларусь  
Дата: 22.10.02 09:58
Оценка:
Здравствуйте Dr_Sh0ck, Вы писали:

DS>Поищи по форуму.

Краткость — сестра таланта.
Re[2]: Есть тут один хакер... :)))
От: SVV Беларусь  
Дата: 22.10.02 09:59
Оценка:
Здравствуйте jazzer, Вы писали:

J>Здравствуйте ArickS, Вы писали:


J>Можно поискать слово thunk


J>Или заглянуть в сорцы ATL


А еще лучше понять почему компиллятор ругается...
А то в принципе, компиллятор заставить молчать можно, только проблема будет в другом...
Re: как передать в функцию указатель на метод класса
От: SVV Беларусь  
Дата: 22.10.02 10:09
Оценка:
Здравствуйте ArickS, Вы писали:

AS>Господа программисты ответьте пожалуйста как передать в функцию указатель на метод класса?

AS>Т.е. есть у меня метод
AS>VOID CALLBACK TimerDictionary::TimerProc(HWND hwnd, UINT uMsg, unsigned int idEvent, DWORD dwTime)
AS>надо передать его в функцию :

AS>VOID TimerDictionary::SetTimer()

AS>{
AS> idTimer = SetTimer(0,0,TimeDelay,&TimerProc);
AS>//здесь возникает ошибка
AS>}
Еще бы. Ты пытаешься вщемить 32-бит указатель на функцию + 32 бит указатель на обект в 32 бита ...

Можешь посмотреть ссылку, которую дал тебе RS, но по-моему там навороченно...
Слово static решит одну проблему (компиллятор перестанет ругаться), но создаст другую (потеряешь доступ к переменным объекта класса).

Возможным решением было бы каким-либо образом передавать в твою TimerProc this, либо написать ее так, чтоб она сама получала нужный this.
Re[2]: как передать в функцию указатель на метод класса
От: SVV Беларусь  
Дата: 22.10.02 10:18
Оценка:
При использовании static либо глобальной TimerProc
Re[2]: как передать в функцию указатель на метод класса
От: dupamid Россия  
Дата: 22.10.02 10:21
Оценка:
Здравствуйте SVV, Вы писали:

Пора, видимо, и мне внести свою маленькую лепту.

AS>>Господа программисты ответьте пожалуйста как передать в функцию указатель на метод класса?

AS>>Т.е. есть у меня метод
AS>>VOID CALLBACK TimerDictionary::TimerProc(HWND hwnd, UINT uMsg, unsigned int idEvent, DWORD dwTime)
AS>>надо передать его в функцию :

AS>>VOID TimerDictionary::SetTimer()

AS>>{
AS>> idTimer = SetTimer(0,0,TimeDelay,&TimerProc);
AS>>//здесь возникает ошибка
AS>>}
SVV>Еще бы. Ты пытаешься вщемить 32-бит указатель на функцию + 32 бит указатель на обект в 32 бита ...

У тебя странное представление об указателях на члены класса, они не содержат this, более того они часто бывают размером с обычный указатель. Анатоми указателей на члены клаасов уже обсуждалась.

SVV>Можешь посмотреть ссылку, которую дал тебе RS, но по-моему там навороченно...


Интересно что ты считаешь там лишнее.
Re[3]: как передать в функцию указатель на метод класса
От: SVV Беларусь  
Дата: 22.10.02 10:33
Оценка:
Здравствуйте dupamid, Вы писали:

D>Здравствуйте SVV, Вы писали:


D>Пора, видимо, и мне внести свою маленькую лепту.


AS>>>Господа программисты ответьте пожалуйста как передать в функцию указатель на метод класса?

AS>>>Т.е. есть у меня метод
AS>>>VOID CALLBACK TimerDictionary::TimerProc(HWND hwnd, UINT uMsg, unsigned int idEvent, DWORD dwTime)
AS>>>надо передать его в функцию :

AS>>>VOID TimerDictionary::SetTimer()

AS>>>{
AS>>> idTimer = SetTimer(0,0,TimeDelay,&TimerProc);
AS>>>//здесь возникает ошибка
AS>>>}
SVV>>Еще бы. Ты пытаешься вщемить 32-бит указатель на функцию + 32 бит указатель на обект в 32 бита ...

D>У тебя странное представление об указателях на члены класса, они не содержат this, более того они часто бывают размером с обычный указатель. Анатоми указателей на члены клаасов уже обсуждалась.

Может быть. Это я для простоты (ясности). Конечно же адрес переменной объекта класса = 32 бит, просто чтоб доступиться до него нужно знать this и смещение этой переменной отн. начала стр-ры...

SVV>>Можешь посмотреть ссылку, которую дал тебе RS, но по-моему там навороченно...


D>Интересно что ты считаешь там лишнее.

По ссылке? В целом ничего, т.к. мне показалось, что там слишком много всего, чтобы выполнить предельно простую функцию... Ничего против не имею...
Re[4]: как передать в функцию указатель на метод класса
От: ArickS  
Дата: 26.10.02 13:27
Оценка:
Спасибо вроде разобрался
Re: как передать в функцию указатель на метод класса
От: Demiurg  
Дата: 01.11.02 15:41
Оценка:
Здравствуйте ArickS, Вы писали:

AS>Господа программисты ответьте пожалуйста как передать в функцию указатель на метод класса?

AS>Т.е. есть у меня метод
AS>VOID CALLBACK TimerDictionary::TimerProc(HWND hwnd, UINT uMsg, unsigned int idEvent, DWORD dwTime)
AS>надо передать его в функцию :

AS>VOID TimerDictionary::SetTimer()

AS>{
AS> idTimer = SetTimer(0,0,TimeDelay,&TimerProc);
AS>//здесь возникает ошибка
AS>}


Это же у тебя функция обратного вызова? Так она в любом случае не будет работать, так как у нее фиксированный набор параметров, а ей еще неявно this передается. Я бы ее сделал static (впрочем, я так всегда и делаю), а доступ к объекту получаю через this, вот так:

//****************************************************************************
LRESULT MainWindow::WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
MainWindow *curwin = NULL;
MINMAXINFO *mmi;

curwin = (MainWindow *)GetWindowLong(hwnd, GWL_USERDATA);

 switch(msg)
 ...
  case WM_PAINT:
      if(curwin)curwin->PaintHandler();
 ...


В конструкторе вызывается SetWindowLong(hwnd,GWL_USERDATA,(LONG)this);
Все просто
Re: как передать в функцию указатель на метод класса
От: c-smile Канада http://terrainformatica.com
Дата: 01.11.02 23:31
Оценка:
Здравствуйте ArickS, Вы писали:

AS>Господа программисты ответьте пожалуйста как передать в функцию указатель на метод класса?


В качестве идеи...

допустим твои callback функции описываются шаблоном bool myclass::myfunc(int msg, ...)

Тогда вот такая простая конструкция тебе поможет...

#include <stdarg.h>

template<class C> class callback 
{
  typedef bool (C ::* F)(int msg, ...); 
  C&    o;
  F     pf;
public:
  callback(C& object, F f): o(object),pf(f) {}
  bool call(int msg, ...) 
  {
    va_list va;
    va_start(va,msg); 
    bool r = (o.*pf)(msg,va);
    va_end(va);
    return r;
  }
};



А вот пример использования:
struct exp 
{
  int dummy;
  bool method1(int, ... ) { printf("method1\n"); return true; }
  bool method2(int, ... ) { printf("method2\n"); return true; }
};

// функция в которой активируют callback
void caller(callback<exp>& cb )
{
  cb.call(0,1,2,3,4);
}

int main(int argc, char* argv[])
{
  exp e;
  
  callback<exp> c1( e, exp::method1 );
  callback<exp> c2( e, exp::method2 );

    printf("calling...\n");

  c1.call(0);
  c2.call(0);

  caller(c1);  
  caller(c2);  

    return 0;
}


Приведенный код справедлив для MS VC. GCC использует другую семантику вызова указателя на member function.
Более generic метод описан здесь
Автор: Геннадий Васильев
Дата: 31.10.02
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.