Connecting Tech Pros Worldwide Help | Site Map

Callback to member function

Frank Neuhaus
Guest
 
Posts: n/a
#1: Aug 2 '05
Hi
Iam trying to make a class where you can register callbacks to member
functions of other classes.
I declared the functions I wish to use like this:

void SetMouseProc(ONMOUSEPROC proc, void* pUserData);

where ONMOUSEPROC is this type:

typedef void (*ONMOUSEPROC) (void* pUserData, int iX, int iY);

The type is supposed to "emulate" the __thiscall calling convention, where
the first parameter is always the "this" pointer to the class instance.
That way i should be able to pass any member function to this function, and
the this pointer as userdata and it should work.
Unfortunately it does not.

This is how I call SetMouseProc:

void (CGame::*pf3)(int,int)=&CGame::OnMouse;
ONMOUSEPROC b=*(ONMOUSEPROC*)&pf3;
m_Input.SetMouseProc(b,g_pGame);

For some reason, directly casting the &CGame::OnMouse to (ONMOUSEPROC) didnt
work, so I had to "force" it to the other type :)

The code above is syntactically correct ( and admittedly evil looking ;/ ),
but it crashes as soon as one tries to actually call the callback function.
Any ideas how I could either fix my problem or replace my current hack
solution by a cleaner method?

Thanks in advance


Victor Bazarov
Guest
 
Posts: n/a
#2: Aug 2 '05

re: Callback to member function


Frank Neuhaus wrote:[color=blue]
> Iam trying to make a class where you can register callbacks to member
> functions of other classes.
> I declared the functions I wish to use like this:
>
> void SetMouseProc(ONMOUSEPROC proc, void* pUserData);
>
> where ONMOUSEPROC is this type:
>
> typedef void (*ONMOUSEPROC) (void* pUserData, int iX, int iY);
> [...][/color]

Your question is covered in the FAQ.
Frank Neuhaus
Guest
 
Posts: n/a
#3: Aug 2 '05

re: Callback to member function


Hmm ok thanks ;)
Just wondering:
Ive just been playing around with asm a little and I managed to fake the
thiscall calling convention properly by changing my stuff to this:
typedef void (_cdecl *ONMOUSEPROC) (int iX, int iY);

now a call to this function works like this:

mov esi,esp ;

mov eax,dword ptr [dwY] ;// param 2

push eax ;

mov ecx,dword ptr [dwX] ;// param 1

push ecx ;

mov ecx, dword ptr[userdata];// userdata contains the this pointer to the
class that was passed to the SetMouseProc function earlier

mov edx,dword ptr [this] ;

call dword ptr [edx+8] ; // just the location of the function inside the
class



Now this code works. The callback is issued correctly. Obviously a very
unclean way of doing it. But what Iam asking myself is: Why is there no way
in C++ to do the same? Why shouldnt the user be allowed to "fake" thiscalls?

"Victor Bazarov" <v.Abazarov@comAcast.net> schrieb im Newsbeitrag
news:_oRHe.24732$Tf5.17549@newsread1.mlpsca01.us.t o.verio.net...[color=blue]
> Frank Neuhaus wrote:[color=green]
> > Iam trying to make a class where you can register callbacks to member
> > functions of other classes.
> > I declared the functions I wish to use like this:
> >
> > void SetMouseProc(ONMOUSEPROC proc, void* pUserData);
> >
> > where ONMOUSEPROC is this type:
> >
> > typedef void (*ONMOUSEPROC) (void* pUserData, int iX, int iY);
> > [...][/color]
>
> Your question is covered in the FAQ.[/color]


Pete Becker
Guest
 
Posts: n/a
#4: Aug 2 '05

re: Callback to member function


Frank Neuhaus wrote:[color=blue]
>
> Now this code works. The callback is issued correctly.[/color]

Try it with a virtual function.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Frank Neuhaus
Guest
 
Posts: n/a
#5: Aug 3 '05

re: Callback to member function


It is already virtual, because the CGame class is an abstract base class.

"Pete Becker" <petebecker@acm.org> schrieb im Newsbeitrag
news:WPWdnaotidyfb3LfRVn-vA@rcn.net...[color=blue]
> Frank Neuhaus wrote:[color=green]
> >
> > Now this code works. The callback is issued correctly.[/color]
>
> Try it with a virtual function.
>
> --
>
> Pete Becker
> Dinkumware, Ltd. (http://www.dinkumware.com)[/color]


Pete Becker
Guest
 
Posts: n/a
#6: Aug 3 '05

re: Callback to member function


Frank Neuhaus wrote:[color=blue]
> It is already virtual, because the CGame class is an abstract base class.
>[/color]

I didn't read your code closely enough. You've actually simulated a
simple virtual call there. The comment on the actual call is slightly
incorrect: it's not the location of the function inside the class, but
the location of the function pointer in the class's vtable. But that
particular calling sequence won't work with a non-virtual function, and
might or might not work when the this pointer points to a virtual base,
and won't work with an implementation that doesn't lay objects out the
same way as your compiler. Pointers to member functions hide all this
detail, all of which is implementation-specific, anyway.

This sort of asm-level hacking should only be done in the privacy of
your own home. <g>

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Frank Neuhaus
Guest
 
Posts: n/a
#7: Aug 3 '05

re: Callback to member function


Of course thats not a nice code and I wouldnt use it in my program anyway.
But iam simply wondering why its not possible to use the thiscall calling
convention just like any other?

"Pete Becker" <petebecker@acm.org> schrieb im Newsbeitrag
news:8fCdnWM3ap1Fkm3fRVn-oA@rcn.net...[color=blue]
> Frank Neuhaus wrote:[color=green]
> > It is already virtual, because the CGame class is an abstract base[/color][/color]
class.[color=blue][color=green]
> >[/color]
>
> I didn't read your code closely enough. You've actually simulated a
> simple virtual call there. The comment on the actual call is slightly
> incorrect: it's not the location of the function inside the class, but
> the location of the function pointer in the class's vtable. But that
> particular calling sequence won't work with a non-virtual function, and
> might or might not work when the this pointer points to a virtual base,
> and won't work with an implementation that doesn't lay objects out the
> same way as your compiler. Pointers to member functions hide all this
> detail, all of which is implementation-specific, anyway.
>
> This sort of asm-level hacking should only be done in the privacy of
> your own home. <g>
>
> --
>
> Pete Becker
> Dinkumware, Ltd. (http://www.dinkumware.com)[/color]


Pete Becker
Guest
 
Posts: n/a
#8: Aug 3 '05

re: Callback to member function


Frank Neuhaus wrote:[color=blue]
> Of course thats not a nice code and I wouldnt use it in my program anyway.
> But iam simply wondering why its not possible to use the thiscall calling
> convention just like any other?
>[/color]

You'll have to ask Microsoft. There's no thiscall calling convention in
Standard C++. Just extern "C" and extern "C++", both of which
potentially involve the calling convention, among other things.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Closed Thread