вторник, 19 мая 2009 г.

Old tricks: The way to use member function for C-style callback

template <class T> class Thunk
{
BYTE asm86[12];
public:
typedef void (__stdcall T::*ThunkType)();

void InitThunk(ThunkType method, const T *pthis)
{
union uPtr { BYTE *byte; DWORD *dword; ThunkType method; };

uPtr pAsm86;
pAsm86.byte = asm86;
uPtr pFn;
pFn.method = method;

*pAsm86.byte++ = 0x58; //pop eax
*pAsm86.byte++ = 0x68; //push pthis
*pAsm86.dword++ = (DWORD)pthis;
*pAsm86.byte++ = 0x50; //push eax
*pAsm86.byte++ = 0xE9; //jmp method
*pAsm86.dword++ = (DWORD)pFn.dword - (DWORD)(this+1);

//This function is valid only on multiprocessor computers.
//FlushInstructionCache(GetCurrentProcess(), this, sizeof(*this));
}

FARPROC GetThunk() const
{
return (FARPROC)this;
}
};
class Window : private Thunk<Window>
{
LRESULT CALLBACK WindowProc(HWND,UINT,WPARAM,LPARAM);
public:
Window()
{
InitThunk((Thunk<Window>::ThunkType)WindowProc,this);
WNDCLASSEX wc;
wc.lpfnWndProc=(WNDPROC)GetThunk();
}
};

Комментариев нет:

Отправить комментарий