C/C++

 

 

 

 

Callback/Function Pointer

 

Callback is a mechanism to pass a function (not a value) to another function as an argument. Most of the readers who has even a little bit of programming experience creating a function. But almost of all (or every) functions that you have created would be the function without any parameter at all (or called function with void parameters) or function with value parameter (e.g, parameter in the form of int, char, char*, struct etc) and you may not know that you can pass a function as a parameter. It would be difficult to understand what it is if you don't try on your own. Just try a couple of examples shown here.

 

 

Example 1 > Callback function with no return (void return)

This example shows a case of a callback function that performs an operation without returning a value. It's typically used for actions that have an effect but do not produce a result to be used in subsequent code.

  • Use Case: Suitable for operations where the calling function does not need a result from the callback, like logging or simple notifications.
  • Pros: Simplicity in usage and implementation.
  • Cons: Limited functionality as it doesn't return any value to the calling function

#include <stdio.h>

 

void PrintMsg()

{

    printf("Hello World");

}

 

// This function takes in a function as an argument

void RunCallBack(void (*ptrFunc)())

{

    

    ptrFunc();

    

}

 

int main()

{

    // The address of the function PrintMsg() is passed as an argument to RunCallBack()

    RunCallBack(&PrintMsg);

}

 

Result :----------------------------------

 

Hello World

 

 

Example 2 > Callback function with return

This example shows a callback function that performs a calculation or processes data and returns a value. It's useful for operations where the caller needs the result of the callback.

  • Use Case: Useful when the output from the callback is required, for example, transformations or calculations.
  • Pros: Can return data which can be further used or processed.
  • Cons: Slightly more complex due to the management of returned data.

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

char* PrintMsg()

{

    return "Hello World";

}

 

// This function takes in a function as an argument

void RunCallBack(char* (*ptrFunc)())

{

    

    char* msg;

    msg = (char *)malloc(255);

    

    strcpy(msg,ptrFunc());

        

    printf("%s",msg);

}

 

int main()

{

     // The address of the function PrintMsg() is passed as an argument to RunCallBack()

    RunCallBack(&PrintMsg);

}

 

 

Result :----------------------------------

 

Hello World

 

 

Example 3 > typedef callback function

This simplifies the use of callback functions by defining a type for the function pointer, making the code cleaner and easier to read and maintain.

  • Use Case: Enhances readability and maintainability of code involving callbacks.
  • Pros: Code is cleaner and easier to manage, especially when similar callbacks are used multiple times.
  • Cons: Abstracts the function pointer, which might confuse new developers unfamiliar with typedefs.

#include <stdio.h>

 

typedef void (*callback)();  // now the void function point can be called as a new type called 'callback'

 

void PrintMsg()

{

    printf("Hello World");

}

 

void RunCallBack(callback ptrFunc)

{

    

    ptrFunc();

    

}

 

int main()

{

    RunCallBack(&PrintMsg);

}

 

Result :-----------------------

 

Hello World

 

 

Example 4 >  Array of Callback function

This example shows a use case of callback function managing multiple callback functions in an array, allowing dynamic invocation of different functions based on the program's state or conditions.

  • Use Case: Allows sequencing multiple operations which can be useful in event-driven programming or state machines.
  • Pros: Flexible and powerful, enabling dynamic calling of different functions.
  • Cons: Complexity increases as managing an array of function pointers can lead to harder to trace bugs and logic errors.

#include <stdio.h>

#include <time.h>

 

typedef void (*callback)();

 

void PrintMsg()

{

    printf("Hello World\n");

}

 

void PrintTime()

{

    

  time_t rawtime;

  struct tm * timeinfo;

 

  time ( &rawtime );

  timeinfo = localtime ( &rawtime );

  printf ( "Current local time and date: %s\n", asctime (timeinfo) );   

  

}

 

void RunCallBack()

{

    

    int i;

    callback aryCallback[2] = {PrintMsg, PrintTime};

    callback ptrFunc;

    

    for( i = 0; i < 2; i++ ) {

        ptrFunc = aryCallback[i];

        ptrFunc();

    }

    

}

 

int main()

{

    RunCallBack();

}