• Welcome to Valhalla Legends Archive.
 

Callback functions and member variables

Started by iago, July 04, 2003, 07:15 AM

Previous topic - Next topic

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
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


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.

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 :)
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Adron

#3
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();





Eibro

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();
Eibro of Yeti Lovers.

Camel

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. :)

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!
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*