C语言回调函数
Callbacks have a wide variety of uses. For example, imagine a function that reads a configuration file and associates values with options. If the options are identified by a hash, then writing the function so that it takes a callback makes it more flexible: its user can choose whatever hashing algorithm is desired and the function will continue to work, since it uses the callback to turn option names into hashes; thus, callbacks allow the user of a function to fine-tune it at runtime. Another use is in error signaling. A Unix program, for example, might not want to terminate immediately when it receives SIGTERM; to make sure things get taken care of, it would register the cleanup function as a callback.
Callbacks may also be used to control whether a function acts or not: Xlib allows custom predicates to be specified to determine whether a program wishes to handle an event. The following code in C demonstrates the use of callbacks to display two numbers.
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 /* The calling function takes a single callback as a parameter. */ 5 void PrintTwoNumbers(int (*numberSource)(void)) { 6 printf("%d and %d\n", numberSource(), numberSource()); 7 } 8 9 /* A possible callback */ 10 int overNineThousand(void) { 11 return (rand() % 1000) + 9001; 12 } 13 14 /* Another possible callback. */ 15 int meaningOfLife(void) { 16 return 42; 17 } 18 19 /* Here we call PrintTwoNumbers() with three different callbacks. */ 20 int main(void) { 21 PrintTwoNumbers(&rand); 22 PrintTwoNumbers(&overNineThousand); 23 PrintTwoNumbers(&meaningOfLife); 24 return 0; 25 }
This should provide output similar to:
125185 and 89187225
9084 and 9441
42 and 42
Note how this is different from simply passing the output of the callback function to the calling function, PrintTwoNumbers() - rather than printing the same value twice, the PrintTwoNumbers calls the callback as many times as it requires. This is one of the two main advantages of callbacks.
The other advantage is that the calling function can pass whatever parameters it wishes to the called functions (not shown in the above example). This allows correct information hiding: the code that passes a callback to a calling function does not need to know the parameter values that will be passed to the function. If it only passed the return value, then the parameters would need to be exposed publicly.[examples needed]
Another example:
1 /* 2 * This is a simple C program to demonstrate the usage of callbacks 3 * The callback function is in the same file as the calling code. 4 * The callback function can later be put into external library like 5 * e.g. a shared object to increase flexibility. 6 * 7 */ 8 9 #include <stdio.h> 10 #include <string.h> 11 #include <stdlib.h> 12 13 typedef struct _MyMsg { 14 int appId; 15 char msgbody[32]; 16 } MyMsg; 17 18 void myfunc(MyMsg *msg) 19 { 20 if (strlen(msg->msgbody) > 0 ) 21 printf("App Id = %d \n Msg = %s \n",msg->appId, msg->msgbody); 22 else 23 printf("App Id = %d \n Msg = No Msg\n",msg->appId); 24 } 25 26 /* 27 * Prototype declaration 28 */ 29 void (*callback)(void *); 30 31 int main(void) 32 { 33 MyMsg msg1; 34 msg1.appId = 100; 35 strcpy(msg1.msgbody, "This is a test\n"); 36 37 /* 38 * Assign the address of the function 'myfunc' to the function 39 * pointer 'callback' 40 */ 41 callback = (void *)myfunc; 42 43 /* 44 * Call the function 45 */ 46 callback((MyMsg*)&msg1); 47 48 return 0; 49 }
The output after compilation:
$ gcc cbtest.c
$ ./a.out
App Id = 100
Msg = This is a test