CALLBACK - функция член класса
От: sincosltd  
Дата: 21.11.03 08:42
Оценка:
Такой вопрос —
может ли функция класса быть каллбаком?

class a
{
private:
//***********
public:
void F()
HRESULT WINAPI EnumModesCallback(LPVOID lpContext,.....)
}

a::f()
{
SomeFunction(...,...,EnumModesCallback)
}

когда я пытаюсь вызывать каллбак из функции — компилятор ругается
о не возможности преобразовать типы. Я так думаю, что компилятор не может вычислить
адрес ф-ции. Если эту ф-ю вынести вверх за пределы класса вообще — всё прекпасно работает.
Может как то через this нужно делать?
Re: CALLBACK - функция член класса
От: Vamp Россия  
Дата: 21.11.03 08:43
Оценка: +1
Здравствуйте, sincosltd, Вы писали:

S>Такой вопрос —

S>может ли функция класса быть каллбаком?
Oh boy!
Поиском не пробовал воспользоваться?
Да здравствует мыло душистое и веревка пушистая.
Re: CALLBACK - функция член класса
От: aik Австралия  
Дата: 21.11.03 08:52
Оценка:
Здравствуйте, sincosltd, Вы писали:

S>Такой вопрос —

S>может ли функция класса быть каллбаком?

да. делай ее статиком. даже круче — сделай 2 функции — одну со статиком, другую — без. и посмотри в ассемблере разницу.
Re[2]: CALLBACK - функция член класса
От: sincosltd  
Дата: 21.11.03 21:00
Оценка:
Здравствуйте, Vamp, Вы писали:

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


S>>Такой вопрос —

S>>может ли функция класса быть каллбаком?
V>Oh boy!
V>Поиском не пробовал воспользоваться?
пробовал, и варианты ответов пробовал — толку ноль

проблема в том что мне нужно передать в ДиректХ функцию — каллбак :
hRet = dd7->EnumDisplayModes(DDEDM_REFRESHRATES,NULL,(void*) hwnd,EnumDisplayModes);

EnumDisplayModes — ожидается таким как его придумали разработчики директа
и всякие уловки котроые предлагались — передача адреса обьекта итд не проходят...
Статик тоже не помогает...
вот что пишет компилятор:

Cannot convert 'long (__stdcall * (_closure )(_DDSURFACEDESC2 *,void *))(_DDSURFACEDESC2 *,void *)' to 'long (__stdcall *)(_DDSURFACEDESC2 *,void *)' in function ...

вопрос как преобразовать?
Re[3]: CALLBACK - функция член класса
От: Аноним  
Дата: 21.11.03 21:32
Оценка:
Здравствуйте, sincosltd, Вы писали:

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


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


S>>>Такой вопрос —

S>>>может ли функция класса быть каллбаком?
V>>Oh boy!
V>>Поиском не пробовал воспользоваться?
S>пробовал, и варианты ответов пробовал — толку ноль

S>проблема в том что мне нужно передать в ДиректХ функцию — каллбак :

S>hRet = dd7->EnumDisplayModes(DDEDM_REFRESHRATES,NULL,(void*) hwnd,EnumDisplayModes);

S>EnumDisplayModes — ожидается таким как его придумали разработчики директа

S>и всякие уловки котроые предлагались — передача адреса обьекта итд не проходят...
S>Статик тоже не помогает...
S>вот что пишет компилятор:

S>Cannot convert 'long (__stdcall * (_closure )(_DDSURFACEDESC2 *,void *))(_DDSURFACEDESC2 *,void *)' to 'long (__stdcall *)(_DDSURFACEDESC2 *,void *)' in function ...


S>вопрос как преобразовать?


Покажи, как ты объявляешь свой callback
и место, где ты его используешь.

А вообще, этот вопрос уже действительно много раз задавался.
Вот из последнего:
http://www.rsdn.ru/Forum/Message.aspx?mid=447128&only=1
Автор: Dimeon
Дата: 18.11.03

http://www.rsdn.ru/Forum/Message.aspx?mid=3128&only=1
Автор: Нартов Андрей Евгеньевич
Дата: 17.07.01


Censored, нарушение п. 6 правил форумов RSDN.ru. — ПК.
Re: CALLBACK - функция член класса
От: Yess  
Дата: 22.11.03 07:32
Оценка:
Здравствуйте, sincosltd, Вы писали:

S>Такой вопрос —

S>может ли функция класса быть каллбаком?
...
S>когда я пытаюсь вызывать каллбак из функции — компилятор ругается
S>о не возможности преобразовать типы. Я так думаю, что компилятор не может вычислить
S>адрес ф-ции. Если эту ф-ю вынести вверх за пределы класса вообще — всё прекпасно работает.
S>Может как то через this нужно делать?


Вот так можно, но это непереносимо и наглый хак, хотя идея из ATL

#include <windows.h> 

#pragma pack(push,1) 
struct _ProcThunk 
{ 
   DWORD   m_mov;          
   DWORD   m_this;          
   BYTE    m_jmp;          
   DWORD   m_relproc;      
}; 
#pragma pack(pop) 

class ProcThunk 
{ 
public: 
   union 
   { 
      _ProcThunk thunk; 
   }; 
   void Init(void* proc, void* pThis) 
   { 
      thunk.m_mov = 0x042444C7; 
      thunk.m_this = (DWORD)pThis; 
      thunk.m_jmp = 0xe9; 
      thunk.m_relproc = (int)proc - ((int)this+sizeof(_ProcThunk)); 
      FlushInstructionCache(GetCurrentProcess(), &thunk, sizeof(thunk)); 
   } 
}; 

__declspec (naked) void* _cdecl pvoid_cast(...) 
{ 
   _asm 
   { 
      mov eax, [esp+4] 
      ret 
   } 
} 

class Thread 
{ 
   ProcThunk thunk_; 
public: 
   DWORD Worker(void* p) 
   { 
      ::MessageBox("Thread", "Thread", 0, 0); 
      return 0; 
   } 

   Thread() 
   { 
      thunk_.Init(pvoid_cast(Worker), (void*)this); 
   } 
    
   operator LPTHREAD_START_ROUTINE() 
   { 
      return (LPTHREAD_START_ROUTINE)&(thunk_.thunk); 
   } 
}; 

int main(int argc, char* argv[]) 
{ 
   Thread t; 

   HANDLE hThread = CreateThread(NULL, 0, t, NULL, 0, 0 ); 
    
   WaitForSingleObject(hThread, INFINITE); 

   return 0; 
}
Re[2]: CALLBACK - функция член класса
От: Аноним  
Дата: 22.11.03 07:49
Оценка:
Здравствуйте, Yess, Вы писали:

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


S>>Такой вопрос —

S>>может ли функция класса быть каллбаком?
Y>...
S>>когда я пытаюсь вызывать каллбак из функции — компилятор ругается
S>>о не возможности преобразовать типы. Я так думаю, что компилятор не может вычислить
S>>адрес ф-ции. Если эту ф-ю вынести вверх за пределы класса вообще — всё прекпасно работает.
S>>Может как то через this нужно делать?


Y>Вот так можно, но это непереносимо и наглый хак, хотя идея из ATL


<...>

По-моему применительно к CreateThread этот хак не стоит применять. У ThreadProc и так есть параметр LPVOID lpParameter. С другой стороны, для любых других применений требуется настройка, так как первый параметр функции (который заменяется на pThis) нужно где-то сохранять (в классе ? но тогда он должен быть написан специально). Короче, техника полезная, но использовать её стоит только когда "сильно прижмёт".
Re[3]: CALLBACK - функция член класса
От: Шахтер Интернет  
Дата: 22.11.03 08:26
Оценка:
Здравствуйте, sincosltd, Вы писали:

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


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


S>>>Такой вопрос —

S>>>может ли функция класса быть каллбаком?
V>>Oh boy!
V>>Поиском не пробовал воспользоваться?
S>пробовал, и варианты ответов пробовал — толку ноль

S>проблема в том что мне нужно передать в ДиректХ функцию — каллбак :

S>hRet = dd7->EnumDisplayModes(DDEDM_REFRESHRATES,NULL,(void*) hwnd,EnumDisplayModes);

S>EnumDisplayModes — ожидается таким как его придумали разработчики директа

S>и всякие уловки котроые предлагались — передача адреса обьекта итд не проходят...
S>Статик тоже не помогает...
S>вот что пишет компилятор:

S>Cannot convert 'long (__stdcall * (_closure )(_DDSURFACEDESC2 *,void *))(_DDSURFACEDESC2 *,void *)' to 'long (__stdcall *)(_DDSURFACEDESC2 *,void *)' in function ...


S>вопрос как преобразовать?


Очень хочется ругаться матом. Одна из стандартнейших вещей. Показываю.

struct Callback
 {
  HRESULT method(PDDMODDESC lpDDModeDesc); // этот метод будет вызываться
    
  static HRESULT __stdcall Adapter(PDDMODDESC lpDDModeDesc, LPVOID lpContext);
 };

HRESULT __stdcall Callback::Adapter(PDDMODDESC lpDDModeDesc, LPVOID lpContext)
 {
  return static_cast<Callback *>(lpContext)->method(lpDDModeDesc);
 }
 
...

Callback object; 

dd7->EnumDisplayModes(DDEDM_REFRESHRATES, NULL , &object ,Callback::Adapter);

...


Подобным же образом отрабатывются и другие функции-перечислители, а также CreateThread.
... << RSDN@Home 1.1 beta 2 >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[3]: CALLBACK - функция член класса
От: LaptevVV Россия  
Дата: 22.11.03 08:33
Оценка:
Здравствуйте, sincosltd, Вы писали:

S>>>Такой вопрос —

S>>>может ли функция класса быть каллбаком?
Только статической? Обычные мемберы имеют скрытый параметр this
А если у тебя apiшная ф-я, то у нее лишнихпараметров быть не должно.
S>проблема в том что мне нужно передать в ДиректХ функцию — каллбак :
S>hRet = dd7->EnumDisplayModes(DDEDM_REFRESHRATES,NULL,(void*) hwnd,EnumDisplayModes);
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[3]: CALLBACK - функция член класса
От: .h  
Дата: 22.11.03 20:07
Оценка:
Здравствуйте, Аноним, Вы писали:

А>По-моему применительно к CreateThread этот хак не стоит применять. У ThreadProc и так есть параметр LPVOID lpParameter. С другой стороны, для любых других применений требуется настройка, так как первый параметр функции (который заменяется на pThis) нужно где-то сохранять

Этот хак основывается на том, что this передается в ecx.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.