There are two ways to do this that I am aware of, depending on the type of method.
In the code examples below, I’ll assume our class that has the callbacks is
void newButtonCallback(const Event *ev, void * data);
static void ExitProgram(const Event *ev, void * data);
void EventHandlers::newButtonCallback(const Event *ev, void * data)
nout << "Non Static Event Handler";
void EventHandlers::ExitProgram(const Event *ev, void *data)
nout << "request to quit";
The easiest and most straight-foward way is to use static methods - For static methods, it is pretty simple to make a call - just use the qualified name (in this case, EventHandlers::ExitProgram):
If you need to pass an object to the handler, you can always include it in the data variable
If, however, you want to use non-static methods, it gets a little more complicated. There are several ways to do this, I show one below.
First we define a class to contain the static method that is actually called and that can make the call to the non-static method. Here we will define a generic class that can be used for any callback method.
template <class T>
//This defines the type of the method that we are going to call.
//Note that Although I define the exact same arguments as the EventHandler, this is not a requirement
//For those unfamiliar with the syntax, this line defines a new type called "MethodToCall" that is a method that
// is a member of class T that returns a void and takes the arguments (const Event*, void*).
typedef void (T::*MethodToCall)(const Event*, void *);
//This is a structure we use to pass the actual data about which method and class to call.
// Object to call
T * TargetObject;
// Method to call
// This is arbitrary data to pass
void * TargetData;
CallbackDef(T* pTarget, MethodToCall fMethod, void * pData)
TargetObject = pTarget;
TargetMethod = fMethod;
TargetData = pData;
//This is the actual callback that we will be calling - it makes the call to our object.
static void Execute(const Event * ev, void * Data)
//The only valid data is a callbackDef structure
CallbackDef * pDef = (CallbackDef*)Data;
//This line can be broken down into 3 parts.
// (pDef->TargetObject)-> We are calling a method using the TargetObject object.
// *(pDef->TargetMethod) We are calling the TargetMethod method
// (ev,pDef->TargetData) Arguments to our method call.
In the code that sets up the define_key, there is a little extra work that needs to be done as well.
//Create an object, so we have something to call
//Here we define our CallbackDef object. This is an object of type
//StaticCallback<EventHandlers>::CallbackDef which will define a call to a method in an EventHandlers class
//Our TargetOject is EH
//Our TargetMethod is EventHandlers::newButtonCallback
//And we are not passing any extra data
//Define our call to the StaticCallback<T>::Execute method and pass in our CallbackDef object.
One nice thing about this implementation is that it is possible to change the object and even the method assigned to that event on the fly (by just changing (in this example), the pointers in oDefinition.). On the other hand, it is definately more involved than the other method, although there are several ways to make this simpler from a usage standpoint.