Sign in to follow this  
floatingwoods

callback addresses in std::vector

Recommended Posts

Hello,

I want to implement a cascading callback mechanism, where I call-back several functions in a row. Those functions should be stored in a std::vector for example (because we don't know how many functions will be registered a-priori).

This is how my callback function looks like:

[code]
int callbackFunction(int arg1, int arg2, int arg3, int* arg4, float* arg5)
[/code]

If the user now provides the callbackRegistration function with above address, how do I set-up things on my side? This is what I have so far, but I am at a loss what type should be inside the std::vector<>:

[code]
std::vector<what comes in here?> myCallbackList;

bool registerCallback(int(*callback)(int,int,int,int*,float*))
{
myCallbackList.push_back(callback);
}
[/code]

so that later I can simply call in a loop:

[code]
for (int i=0;i<myCallbackList.size;i++)
result=myCallbackList[i](arg1,arg2,arg3,arg4,arg5);
[/code]


Thanks for any insight

Share this post


Link to post
Share on other sites
[quote]
bool registerCallback(int(*callback)(int,int,int,int*,float*))[/quote]
If "callback" is the name of the variable, what do you think the type is?
<hr>Consider making your argument list a structure. It will ease maintenance if you decide to extend or change your signature in future. It is also a good idea to include a void pointer to opaque data, which allows for arbitrary state during callbacks. You might even be able to remove some of your parameters if you are including them "just in case".

Share this post


Link to post
Share on other sites
Alternately use boost::function and boost::bind to create callbacks that already store the function arguments.

Share this post


Link to post
Share on other sites
Gah! Too slow :D Here's a working program using a typedef

[code]
#include <iostream>
#include <vector>

typedef int (*CallbackTypedef)(int arg1, int arg2, int arg3, int* arg4, float* arg5);

std::vector<CallbackTypedef> myCallbackList;

bool registerCallback(CallbackTypedef _callback)
{
myCallbackList.push_back(_callback);
}


int callBack1(int arg1, int arg2, int arg3, int* arg4, float* arg5)
{
std::cout << "Hello from callback one!\n";
return 0;
}

int callBack2(int arg1, int arg2, int arg3, int* arg4, float* arg5)
{
std::cout << "Hello from callback two!\n";
return 0;
}

int main(void)
{
registerCallback(callBack1);
registerCallback(callBack2);

int result;
int arg4;
float arg5;

for (int i=0;i<myCallbackList.size();i++)
result=(*myCallbackList[i])(0,1,2,&arg4,&arg5);

return 0;

}

[/code]

Share this post


Link to post
Share on other sites
Thanks a lot Gazliddon :)



[quote name='gazliddon' timestamp='1298306684' post='4777091']
Gah! Too slow :D Here's a working program using a typedef

[code]
#include <iostream>
#include <vector>

typedef int (*CallbackTypedef)(int arg1, int arg2, int arg3, int* arg4, float* arg5);

std::vector<CallbackTypedef> myCallbackList;

bool registerCallback(CallbackTypedef _callback)
{
myCallbackList.push_back(_callback);
}


int callBack1(int arg1, int arg2, int arg3, int* arg4, float* arg5)
{
std::cout << "Hello from callback one!\n";
return 0;
}

int callBack2(int arg1, int arg2, int arg3, int* arg4, float* arg5)
{
std::cout << "Hello from callback two!\n";
return 0;
}

int main(void)
{
registerCallback(callBack1);
registerCallback(callBack2);

int result;
int arg4;
float arg5;

for (int i=0;i<myCallbackList.size();i++)
result=(*myCallbackList[i])(0,1,2,&arg4,&arg5);

return 0;

}

[/code]

[/quote]

Share this post


Link to post
Share on other sites
If you don't want to re-inventing the wheel, a container of callbacks is often called a "signal". What you are trying to implement is probably close to a signal/slot system. Boost has a good library for this.

Share this post


Link to post
Share on other sites
boost::function and boost::bind are indispensable if you need actual function objects. "callback" functions cannot operate on class instances in any generic way, so if you ever find yourself needing a vector of function calls, each into an entirely different object and/or method, then boost is your best friend.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this