Skip to main content
GameDev.net gamedev.net
🔒 Locked

callback functions taking arguments

Started by keethrus Dec 18, 2002 at 10:50 PM 6 replies 200+ views
Original Post
keethrus
keethrus
if you just had a pointer to a function, and wanted to call it for whatever reason (callback function for a custom GUI im making in my case), how would you go about having the callback function called but with arguments passed to it. in my case, i want a callback function for a GUI button. when the button is clicked, a function is called - but i want the function called with arguments. how could i do this? ex:

// basic pseudo code
class GUIButton
{
  // blah blah blah

  func_pointer *function_to_be_called_when_button_is_clicked;
}

int x;
x = 3;

myButton = new GUIButton;
myButton.func_pointer = &some_func(x);
// not only call function that func_pointer points to, but also
// send along the argument "x".
 
is this possible? - jeremiah inlovewithGod.com
keethrus
keethrus
thanx for your reply AP.

however, i would appreciate some feedback on my pseudo code. that if it is possible, could you implement it the way i suggested? if not, what would need to be changed?

- jeremiah

inlovewithGod.com
ga
ga
// basic pseudo code
class GUIButton
{ // blah blah blah
RETURN_TYPE (*function_to_be_called_when_button_is_clicked)(int arg0);
};

int x;
x = 3;
GUIButton *myButton = new GUIButton;
myButton.function_to_be_called_when_button_is_clicked =
some_func;// assign some_func to the function pointer

myButton.function_to_be_called_when_button_is_clicked(x); //call the function
Visit our homepage: www.rarebyte.de.stGA
Qw3r7yU10p!
Qw3r7yU10p!
you want to bind the value of x to the function pointer so that when it''s called that value is used?

i think that''s possible using the binder in the standard library but i can''t think of it right now.

be right back
Fruny
Fruny
boost::function and boost::bind have been designed to solve that very problem.


  
#include <boost/function.hpp>
#include <boost/bind.hpp>

using namespace boost;

class Button
{
static void Click( Button* );

// could also have been a member function taking no arguments :

// void Click(); in which case bind (below) would have bound

// the ''this'' parameter to &myButton.

};

Button myButton;

// function object taking zero arguments, returning void

function0<void> myCallback;

// bind &myButton to the first argument of Button::Click

// and store the resulting function (zero arguments, void return)

// in the callback function object.


myCallback = bind( &Button::Click, // function to call

&myButton // pass as first (or this) argument to Button::Click

);

// call it

myCallback();
// calls Button::Click( &myButton );

// or myButton.Click(); if it were a member function




Of course, since it is a function object and not a function pointer, it is not compatible with APIs that require function pointers. But if you''re creating one of your own, it can be helpful.

If your function takes extra arguments, no problem :


  
#include <boost/function.hpp>
#include <boost/bind.hpp>

using namespace boost;

class Button
{
static void Click( Button*, int arg1, int arg2 );

// could also have been a member function :

// void Click( int arg1, int arg2 );

};

Button myButton;

// function object taking two arguments (int, int), returning void

function1<void, int, int> myCallback;

// bind &myButton to the first argument of Button::Click,

// the second argument (arg1) will receive the first argument _1 during the call

// the thirsd argument (arg2) will receive the second argument _2 during the call


myCallback = bind( &Button::Click, // function to call

&myButton, // pass as first (or this) argument to Button::Click

_1, // first formal argument of myCallback

_2, // second formal argument of myCallback

);

// The first argument goes into _1, the second into _2

myCallback( 10, 20 );
// calls Button::Click( &myButton, 10, 20 );

// or myButton.Click( 10, 20 ); if it were a member function



For more information, follow the Boost link in my signature, and look at the function and bind documentation there.


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
keethrus
keethrus
sweetness...

fruny, that is exactly what i was looking for. thanx a bunch! :-)

while this will definately solve my problem, im curious as to how "bind" actually works. the docs on it didnt seem to explain how it works, only how to use it. could anybody explain how bind works to an inquiring soul? :-D

- jeremiah

inlovewithGod.com

[edited by - keethrus on December 19, 2002 10:16:19 AM]
Fruny
Fruny
quote:
Original post by keethrus
could anybody explain how bind works to an inquiring soul?



You could ask on the Boost mailing list, or (gasp) study the headers. My own understanding is very limited

Bind basically recognizes the type of your function and generate a function object that stores a function pointer and a copy of the parameters you passed - since it passes a copy, you must wrap the parameter with boost::ref() if you want pass-by-reference. It then hands them to the function pointer when you do the call.

As to how exactly it handles _1 to _9 ... I have no idea. More template trickery ( each _N is an object of a unique type ).

Oh, and here's a cool thing :


void myFunction();
Button myButton;
Window myWindow;

function0 myCallback;
myCallback = bind( &Button::Click, &myButton );
myCallback = bind( &Window::Close, &myWindow );
myCallback = &myFunction


The function object only cares about the final signature of the fucntion. There is no reason to have a single function pointer as parameter in your API, boost::function can absorb just about anything that ressembles a function

Note: also, have a look at boost::signal - it lets you register several functions as a single callback.


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]


[edited by - Fruny on December 19, 2002 11:29:37 AM]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.