Valhalla Legends Forums Archive | General Programming | Callback functions and member variables

AuthorMessageTime
iago
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
July 4, 2003, 12:15 PM
Adron
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.
July 4, 2003, 2:03 PM
iago
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 :)
July 4, 2003, 2:05 PM
Adron
[quote author=iago link=board=5;threadid=1798;start=0#msg13825 date=1057327530]
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]

Kind of like this is what I had in mind, it's a "standard" way of doing it:

[code]
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;
}
[/code]

and now having

[code]
aclass a;
bclass b;
[/code]

you could in a function in "a" do

[code]
callback1 = b;
[/code]

and at some later time do

[code]
callback1->Event1();
[/code]



July 4, 2003, 2:14 PM
Eibro
[quote author=iago link=board=5;threadid=1798;start=0#msg13819 date=1057320916]
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
[/quote]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();
July 4, 2003, 6:16 PM
Camel
[quote author=iago link=board=5;threadid=1798;start=0#msg13825 date=1057327530]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]
I wrote a pseudo-gui class using function pointers and multiple threads for an 'Into to C++' class just to piss off the teacher. :)
July 4, 2003, 7:21 PM
iago
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!
July 5, 2003, 12:18 AM

Search