Use of Callbacks in Layered Architecture - GeeksforGeeks

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(){    // Calling register_callback function and     // passing address of notify_observer as argument    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>)
// Below is the prototype of the function // that will be actually passed by reference 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;  // Callback functionvoid lowerlevelfunction(){     // Calling back to notify_observer    g_notify_ob(); }  // Callback registrationvoid 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 
C-Functions
Technical Scripter 2018
Computer Networks
Computer Networks
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Advanced Encryption Standard (AES)
Block Cipher modes of Operation
Intrusion Detection System (IDS)
Cryptography and its Types
Transport Layer responsibilities
GSM in Wireless Communication
Multiple Access Protocols in Computer Network
Stop and Wait ARQ
Active and Passive attacks in Information Security
Difference between Distance vector routing and Link State routing