Use of Callbacks in Layered Architecture
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.
Attention reader! Don’t stop learning now. Get hold of all the important CS Theory concepts for SDE interviews with the CS Theory Course at a student-friendly price and become industry ready.
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
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>)
Now this is lowerlayer.c
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