Use of Callbacks in Layered Architecture
Last Updated :
05 Feb, 2019
From OSI model of network to Operating System, any daily life project is based on layered architecture. Ever thought how the abstraction between upper layers and lower layers are created?
It is all about callbacks. So, in general upper layers are created to make things simpler and easier to use (like SDKs) and lower layers are the actual layers which interact with network (for a networking based project) or system level calls (for OS based projects). So, we can directly call a function, defined (and declared also) in lower layer, from a upper layer source file and pass the data through function arguments. But, we can not just call a function of upper layer from lower layers, as that will create a circular dependency. So, here Callbacks come into picture.
Callback is the way of passing a function through it’s reference as argument of another function and calling it later by the reference.
Let’s say upperlayer.c and lowerlayer.c are a sourcefiles of upper layer and lower layer respectively. lowerlayer.h is the header file of lowerlayer.c. In the upperlayer.c, first the function reference of notify_observer() is passed to the lowerlayer.c as an argument of register_callback(). This is called registering callback in the lower layer. Now, the lower layer knows about the function reference of notify_observer(). The register_callback() function just stores the function reference into a global function pointer g_notify_ob, so that any function from the file can call notify_observer(). Now, whenever the lower layer needs to pass data to upper layer (or needs to send a notification), it just calls notify_observer() by the calling g_notify_ob().
Below is upperlayer.c
#include <stdio.h>
#include "lowerlayer.h"
void notify_observer()
{
printf ( "Function called by callback\n" );
}
int main()
{
register_callback(notify_observer);
lowerlevelfunction();
}
|
This is lowerlayer.h. The highlighted line is just to denote the prototype of the callback function that will be actually passed as reference. The basic template of the prototype is like,
typedef <Function return type> (*<Name of the function pointer type>)
(<Type of Function arguments separated by comma>)
typedef void (*notify_ob)( void );
void register_callback(notify_ob);
void lowerlevelfunction();
|
Now this is lowerlayer.c
#include "lowerlayer.h"
#define NULL 0
notify_ob g_notify_ob;
void lowerlevelfunction()
{
g_notify_ob();
}
void register_callback(notify_ob fun)
{
g_notify_ob = fun;
}
|
If we compile and run these files like these, the output will be like this.
$gcc -c upperlayer.c
$gcc -c lowerlayer.c
$gcc -o exe upperlayer.o lowerlayer.o
$./exe
Output: Function called by callback
Share your thoughts in the comments
Please Login to comment...