I have a class [let's call it class a] which uses several callbacks [defined as, "typedef void (WSCALLBACK)(char *,DWORD);"], and I want to set the callbacks to a non-static member function of a different class [let's call it class b]. It gives me errors when I just do "ptr_b->SetCallback( this->Callbackfunc );" or "ptr_b->SetCallback( CallbackFunc);".
Now, I'm pretty sure that the problem is that member functions have that evil hidden variable "this," which is making the signature different.
My problem is that I have non-static member variables in class b that I need to access from CallbackFunc, so I can't make CallbackFunc a static or a non-member function. I was thinking of doing this:
typedef void (WSCALLBACK)(void *this,char *,DWORD);
And pass "this" every time a callback function is called, but if there's a better way to do it, I would like to know.
Any ideas?
Thanks!
-iago
The best way I know for callback functions in classes is to make it a static member function and pass a pointer to the class instance as an argument. No reason to make it a void* too.
You can't call a regular member function as if it was a non-member function by adding an argument, because the calling convention is different for member and non-member functions. For msvc you could do it by declaring it fastcall and passing two extra arguments, but it's really not the right way to go.
Question: Do you really have to mess with function pointers at all? What in C is often solved with callback functions can in C++ be solved with a base class having a set of virtual functions that you call.
I did consider having a baseclass and subclasses instead, but the problem is the two classes are totally unrelated to each other. I will, however, consider it, since function pointers have gotten me into a fine mess it would seem :)
Quote from: iago on July 04, 2003, 09:05 AM
I did consider having a baseclass and subclasses instead, but the problem is the two classes are totally unrelated to each other. I will, however, consider it, since function pointers have gotten me into a fine mess it would seem :)
Kind of like this is what I had in mind, it's a "standard" way of doing it:
class EventHandlerType1 {
public:
virtual void Event1(void) = 0;
}
class aclass {
.... your stuff here ....
EventHandlerType1 *callback1;
};
class bclass : public EventHandlerType1 {
.... your stuff here ....
public:
virtual void Event1(void);
};
void bclass::Event1(void)
{
cout << "Something happened!" << endl;
}
and now having
aclass a;
bclass b;
you could in a function in "a" do
callback1 = b;
and at some later time do
callback1->Event1();
Quote from: iago on July 04, 2003, 07:15 AM
I have a class [let's call it class a] which uses several callbacks [defined as, "typedef void (WSCALLBACK)(char *,DWORD);"], and I want to set the callbacks to a non-static member function of a different class [let's call it class b]. It gives me errors when I just do "ptr_b->SetCallback( this->Callbackfunc );" or "ptr_b->SetCallback( CallbackFunc);".
Now, I'm pretty sure that the problem is that member functions have that evil hidden variable "this," which is making the signature different.
My problem is that I have non-static member variables in class b that I need to access from CallbackFunc, so I can't make CallbackFunc a static or a non-member function. I was thinking of doing this:
typedef void (WSCALLBACK)(void *this,char *,DWORD);
And pass "this" every time a callback function is called, but if there's a better way to do it, I would like to know.
Any ideas?
Thanks!
-iago
I don't suppose you were using pointer-to-function syntax when you were supposed to be using pointer-to-member-function syntax? typedef void (T::*FunctionPointer)(); as opposed to typedef void (*FunctionPointer();
Quote from: iago on July 04, 2003, 09:05 AMI did consider having a baseclass and subclasses instead, but the problem is the two classes are totally unrelated to each other. I will, however, consider it, since function pointers have gotten me into a fine mess it would seem :)
I wrote a pseudo-gui class using function pointers and multiple threads for an 'Into to C++' class just to piss off the teacher. :)
Eibro - I really don't want to make the typedef class specific. Like I said, the classes have nothing to do with each other, and I'm planning on using "class a" for other things, so it won't work.
I think the best solution is Adron's idea.
Thanks!