simple callback function

Callback function is hard to trace, but sometimes it is very useful. Especially when you are designing libraries. Callback function is like asking your user to gives you a function name, and you will call that function under certain condition.

For example, you write a callback timer. It allows you to specified the duration and what function to call, and the function will be callback accordingly. “Run myfunction() every 10 seconds for 5 times”

Or you can create a function directory, passing a list of function name and ask the library to callback accordingly. “Callback success() if success, callback fail() if failed.”

Lets look at a simple function pointer example

void cbfunc()
{
    printf("called");
}

int main ()
{
     /* function pointer */
    void (*callback)(void);

    /* point to your callback function */
    callback=(void *)cbfunc;

   /* perform callback */
   callback();

   return 0;
}

How to pass argument to callback function?
Observered that function pointer to implement callback takes in void *, which indicates that it can takes in any type of variable including structure. Therefore you can pass in multiple arguments by structure.

typedef struct _myst
{
    int a;
    char b[10];
}myst;

void cbfunc(myst *mt)
{
    fprintf(stdout,"called %d %s.",mt->a,mt->b);
}

int main()
{

    /* func pointer */
    void (*callback)(void *);

    //param
    myst m;
    m.a=10;
    strcpy(m.b,"123");

    /* point to callback function */
    callback = (void*)cbfunc;

    /* perform callback and pass in the param */
    callback(&m);

    return 0;

}

31 thoughts on “simple callback function

  1. Thank you for the example, please make a change in the first snap shot of code.

    void (*callback)(void *);
    to
    void (*callback)(void);

  2. yup…i agree with vladimir…but we can also do it like this…

    void cbfunc()
    {
    printf(“called”);
    }

    int main ()
    {
    /* function pointer */
    void (*callback)();

    /* point to your callback function */
    callback = &cbfunc;

    /* perform callback */
    callback();

    return 0;
    }

  3. if your function is ” cbfunc(myst *mt)”

    then ur callback function should be “void (*callback)(myst *) ” NOT this “void (*callback)(void) “

  4. i m fine with his code. he explained in a simple manner how to use callback funciton.

  5. Hello All
    i am getting following error while compiling it on linux
    error: invalid conversion from `void*’ to `void (*)(myst*)’
    can anybody plz suggest why it is coming

  6. You’ve kept the whole thing really simple and the explanation is very neatly written. Keep the good work up. :-)

  7. ya i agree with nitin i.e

    if your function is ” cbfunc(myst *mt)”

    then ur callback function should be “void (*callback)(myst *) ” NOT this “void (*callback)(void) “

  8. I am new to Callback, can you make sure your code fixed and compiled, then post it again please. I learn from example, however, your code does not compiled. Thanks!

  9. How do you put this in a class? When I try to make the callback function pointer a member variable pointing to a function in another class, it says ‘void (MyClass::)()’ does not match ‘void(*)()’

  10. Oh, I was forgetting the (void*) in the ‘(void*)blankfunc’. But when I have the (void*) it says “invalid use of member( did you forget the ‘&’?)

  11. I have a doubt.

    i can call the function “cbfunc(myst *mt)” directly.
    then why i am assigning “cbfunc(myst *mt)” function to “callback” function pointer & then calling it.

  12. its not the example of a call back function.it is an example of function pointer

  13. Actually FP is the way to implement Callback. So the way to implement callback is the way in which you call the pointer variable (with/without argument) which is the refference to the function on which it is assigned..

  14. This is how in embedded systems call back functions are used. may seems to be little bit complex but it is easy if u read the comments first

    typedef struct
    {
    int a;
    int b;
    int (* callback)(int a,int b);
    }struct_b;

    /*Assume that this is ur library i,e lower level function*/
    int mylib(struct_b );

    /*Assume that this ur higher level function*/
    int add(int a,int b);

    void main(void)
    {
    int a,b;
    struct_b st_b;

    /*Here u r passing higher level function to lower level function through structure*/
    st_b.callback = add;
    st_b.a = 10;
    st_b.b = 12;
    printf(“sum of a and b is = %d”,mylib(st_b));

    }

    /*This is ur higher level function definition*/
    int add(int a,int b)
    {
    return a+b;
    }

    int mylib(struct_b st_b)
    {
    /*Here u r calling higher level function with the help of call back function*/
    return st_b.callback(st_b.a,st_b.b);
    }

  15. This example just shows how function pointer is used to call a function. Actually 2 seperate threads or process are required to show callback functions.
    One example could be device driver code registering ISR(interupt service routine) with OS and OS calls the ISR(the function) when and interrupt is signalled.

  16. Please provide a similar example in c++, for example using callback functions for handling interrupts.

  17. Declaring
    Declare a function pointer as though you were declaring a function, except with a name like *foo instead of just foo:

    void (*foo)(int);

    Initializing
    You can get the address of a function simply by naming it:

    void foo();
    func_pointer = foo;

    or by prefixing the name of the function with an ampersand:

    void foo();
    func_pointer = &foo;

    Invoking
    Invoke the function pointed to just as if you were calling a function.

    func_pointer( arg1, arg2 );

    or you may optionally dereference the function pointer before calling the function it points to:

    (*func_pointer)( arg1, arg2 );

    Benefits of Function Pointers

    Function pointers provide a way of passing around instructions for how to do something
    You can write flexible functions and libraries that allow the programmer to choose behavior by passing function pointers as arguments
    This flexibility can also be achieved by using classes with virtual functions

  18. thank you all for the great explanation… its the best on the onternet.. love you all

  19. #include
    #include

    //Predeclarations
    class cMyProject;

    template
    class TCallback;

    class cCallback
    {
    public:
    virtual void Execute(int Param) const =0;
    };

    template
    class TCallback : public cCallback
    {
    public:
    TCallback() // constructor
    {
    pFunction = 0;
    }

    typedef void (cInstance::*tFunction)(int Param);

    virtual void Execute(int Param) const
    {
    if (pFunction) (cInst->*pFunction)(Param);
    else printf(“ERROR : the callback function has not been defined !!!!”);
    }

    void SetCallback (cInstance *cInstancePointer,
    tFunction pFunctionPointer)
    {
    cInst = cInstancePointer;
    pFunction = pFunctionPointer;
    }

    private:
    cInstance *cInst;
    tFunction pFunction;
    };

    // Some instances of the Callback class
    TCallback i_Callback_1;
    TCallback i_Callback_2;

    class cMyProject{

    private:

    public:
    // the functions of your project
    void CallbackFox (int Param);
    void CallbackRabbit(int Param);
    void TestTheCallback(cCallback *pCallbackFunction, int Param);
    void CallbackDemo();

    };

    void cMyProject::CallbackRabbit(int Param)
    {
    char Buf[50];
    sprintf(Buf, “Now I’m in Rabbit with Param %d !\n”, Param);
    printf(“%s”,Buf);
    }

    void cMyProject::CallbackFox(int Param)
    {
    char Buf[50];
    sprintf(Buf, “Now I’m in Fox with Param %d !\n”, Param);
    printf(“%s”,Buf);
    }

    void cMyProject::TestTheCallback(cCallback *pCallbackFunction, int Param)
    {
    pCallbackFunction->Execute(Param * Param);
    }

    void cMyProject::CallbackDemo()
    {

    // defining where the callback should jump to
    i_Callback_1.SetCallback(this, &cMyProject::CallbackRabbit);
    i_Callback_2.SetCallback(this, &cMyProject::CallbackFox);

    // now you can pass i_Callback like a pointer to a function
    TestTheCallback(&i_Callback_1, 4);
    TestTheCallback(&i_Callback_2, 5);
    }

    int main(int argc, char* argv[])
    {

    cMyProject* test_ = new cMyProject;
    test_ -> CallbackDemo();
    delete test_;

    return 0;
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>