473,569 Members | 2,406 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Callback to member function

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(ON MOUSEPROC 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)(i nt,int)=&CGame: :OnMouse;
ONMOUSEPROC b=*(ONMOUSEPROC *)&pf3;
m_Input.SetMous eProc(b,g_pGame );

For some reason, directly casting the &CGame::OnMo use 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
Aug 2 '05 #1
7 2544
Frank Neuhaus wrote:
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(ON MOUSEPROC proc, void* pUserData);

where ONMOUSEPROC is this type:

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


Your question is covered in the FAQ.
Aug 2 '05 #2
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.********@com Acast.net> schrieb im Newsbeitrag
news:_o******** ***********@new sread1.mlpsca01 .us.to.verio.ne t...
Frank Neuhaus wrote:
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(ON MOUSEPROC proc, void* pUserData);

where ONMOUSEPROC is this type:

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


Your question is covered in the FAQ.

Aug 2 '05 #3
Frank Neuhaus wrote:

Now this code works. The callback is issued correctly.


Try it with a virtual function.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Aug 2 '05 #4
It is already virtual, because the CGame class is an abstract base class.

"Pete Becker" <pe********@acm .org> schrieb im Newsbeitrag
news:WP******** ************@rc n.net...
Frank Neuhaus wrote:

Now this code works. The callback is issued correctly.


Try it with a virtual function.

--

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

Aug 2 '05 #5
Frank Neuhaus wrote:
It is already virtual, because the CGame class is an abstract base class.


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)
Aug 3 '05 #6
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" <pe********@acm .org> schrieb im Newsbeitrag
news:8f******** ************@rc n.net...
Frank Neuhaus wrote:
It is already virtual, because the CGame class is an abstract base class.


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)

Aug 3 '05 #7
Frank Neuhaus wrote:
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?


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)
Aug 3 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
10856
by: prettysmurfed | last post by:
Hi all I have a bit of a problem, the subject of this post is almost selfexplaing. But here goes: Heres an example of the code I want to implement, its all nice and simple, but the flaw is I can't seem to get the adress of the member function stated properly in the DialogBox function. I thought it was enough to write it as Dialog::DlgProc,...
1
8845
by: pvdm | last post by:
Hi, I am writing an app which encapsulates a multimedia timer. I implemented a TimerProc as static member function and a static member variable pThis as pseudo this variable to access in the static TimerProc function. timeSetEvent uses TimerProc to set the callback function.
11
2455
by: ajay.sonawane | last post by:
Hello ther I read somewhere that callback function should be global or static member function. 1: I could use static member functions but how could I access members of class which ar not static. 2: I could use global function but want to access members of class. Let me know the possible solutions. Regards, Ajay Sonawane
4
2042
by: ma740988 | last post by:
// file sltest.h #ifndef SLTEST_H #define SLTEST_H class CallbackBase // herb shutters gotW source .. { public: virtual void operator()() const { }; virtual ~CallbackBase() = 0; };
4
5130
by: H.B. | last post by:
Hi, I successfully implement a static callback function for my dll usign delegates. Now, I need to use member function instead of static function. How can I make that (in Managed C++). Hugo
2
1840
by: Damien | last post by:
Hi all, I'm messing around with various signal/slot mechanisms, trying to build something lean and fast. I've used libsigc++, and Sarah Thompson's at sigslot.sourceforge.net, and most of the others you can find by Googling, but I wanted to try doing it myself and needed some advice on different approaches. Most signal/slot libraries are...
3
3049
by: ryan.mitchley | last post by:
Hi all I have a class (cPort) that is designed to receive objects and, depending on the type, call a handler (callback) in any descendant of a cProcessBlock class. Callback functions take a shared_ptr<cBaseas a parameter, and return void. The code was working fine, although I have encountered problems (under a Microsoft compiler, of...
6
3441
by: JDT | last post by:
Hi, Can we pass a member function in a class as a callback function? Someone instucted me that I can only use a static functon or a global function as a callback. Your help is appreciated. JD
6
7658
by: smmk25 | last post by:
Before I state the problem, I just want to let the readers know, I am knew to C++\CLI and interop so please forgive any newbie questions. I have a huge C library which I want to be able to use in a .NET application and thus am looking into writing a managed C++ wrapper for in vs2005. Furthermore, this library has many callback hooks which...
2
3633
by: saleemak | last post by:
Hi, I have a problem of how to update the Object data of a Class from within a Callback function that is not a member function of that Class, its just a C function. void CallBack( int reason, Snmp *snmp, Pdu &pdu, SnmpTarget &target, void *cd) // just a C function not a member function { // can i update the contents of the Object
0
7618
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7926
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8132
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
7982
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
3656
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3644
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2116
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1226
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
944
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.