Welcome to a comprehensive guide on Callback Functions in C Programming! In this lesson, we'll dive deep into understanding what callback functions are, why they're important, and how to effectively use them. Let's get started!
Callback functions, often referred to as "higher-order functions," are functions that are passed as arguments to other functions or returned from other functions. They allow you to build modular and reusable code by enabling functions to interact with each other more efficiently.
Let's start with a simple example of a callback function:
#include <stdio.h>
void printNumber(int num) {
printf("The number is: %d\n", num);
}
void callPrintNumber(int num, void (*callback)(int)) {
callback(num);
}
int main() {
int myNumber = 42;
callPrintNumber(myNumber, printNumber);
return 0;
}In the example above, we have defined a function printNumber and a function callPrintNumber. The printNumber function is the callback that takes an integer as an argument and prints it. The callPrintNumber function accepts two argumentsβan integer and a callback functionβand calls the callback with the provided integer.
Callback functions are often used with asynchronous operations. Let's explore an example of a callback function with a network request:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void callback(const char* data) {
printf("Received data: %s\n", data);
}
int create_socket(int *socket_desc) {
int sock = 0, val = 1;
struct sockaddr_in serv_addr;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("Socket creation error\n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(8080);
// Zero-out the struct for initialization
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
serv_addr.sin_addr.s_addr = INADDR_ANY;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
printf("Setsockopt error\n");
return -1;
}
if (bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
printf("bind failed. Error is: %d\n", errno);
return -1;
}
listen(sock, 3);
if (*socket_desc != 0)
close(*socket_desc);
*socket_desc = sock;
return 0;
}
int main(int argc, char *argv[]) {
int socket_desc, addrlen = sizeof(struct sockaddr_in);
create_socket(&socket_desc);
struct sockaddr_in client;
memset((char *) &client, '\0', sizeof(client));
client.sin_family = AF_INET;
client.sin_port = htons(8080);
// convert IPv4 address from text to binary form
if (inet_pton(AF_INET, "127.0.0.1", &client.sin_addr) <= 0) {
printf("Invalid address/ Address not supported\n");
return 1;
}
socklen_t client_len = sizeof(client);
int new_socket = accept(socket_desc, (struct sockaddr *) &client, &client_len);
if (new_socket < 0) {
printf("accept failed\n");
return 1;
}
char buffer[1024] = {0};
read(new_socket, buffer, 1024);
printf("Received data: %s\n", buffer);
return 0;
}In this example, we have a callback function that accepts a string and prints it. The create_socket function creates a socket and waits for a connection. When a connection is established, it reads data from the client and calls the callback function to print the received data.
What is the main purpose of callback functions in C programming?
That's it for our comprehensive guide on C Callback Functions! We've covered the basics of callback functions, their importance, and how to define and use them. Happy coding! π