How to implement callback functions in C?

gcc 4.4.3 c89

I am creating a client server application and I will need to implement some callback functions.

However, I do not know much about callbacks. And I'm wondering if anyone knows of some good reference material when designing callbacks. Are there any design patterns that are used for c. I looked through some templates, but where everything is C ++.

Thanks so much for any suggestions,

+4
source share
3 answers

Here is a very crude example. Note that the only thing I'm trying to demonstrate is the use of callbacks, which should be informative, not a demonstration.

Let's say that we have a library (or any set of functions that revolve around a structure), we will have code similar to this one (of course, I call it foo):

typedef struct foo { int value; char *text; } foo_t; 

It is quite simple. Then we (conditionally) provide some means of allocation and release, such as:

 foo_t *foo_start(void) { foo_t *ret = NULL; ret = (foo_t *)malloc(sizeof(struct foo)); if (ret == NULL) return NULL; return ret; } 

And then:

 void foo_stop(foo_t *f) { if (f != NULL) free(f); } 

But we need a callback, so we can define a function to be introduced when foo->text something. To do this, we use a typed function pointer:

 typedef void (* foo_callback_t)(int level, const char *data); 

We also want any of the foo function families to conveniently use this callback. To do this, we need to add it to the structure, which will now look like this:

 typedef struct foo { int value; char *text; foo_callback_t callback; } foo_t; 

Then we write a function that will actually be introduced (using the same prototype of our callback type):

 void my_foo_callback(int val, char *data) { printf("Val is %d, data is %s\n", val, data == NULL ? "NULL" : data); } 

Then we need to write a convenient way to say which function it actually points to:

 void foo_reg_callback(foo_t *f, void *cbfunc) { f->callback = cbfunc; } 

And then our other foo functions can use it, for example:

 int foo_bar(foo_t *f, char *data) { if (data == NULL) f->callback(LOG_ERROR, "data was NULL"); } 

Please note that in the above example:

 f->callback(LOG_ERROR, "data was NULL"); 

How it's done:

 my_foo_callback(LOG_ERROR, "data was NULL"): 

In addition, we introduce my_foo_callback() using the function pointer that we previously set, thereby giving us the flexibility to define our own handler on the fly (and even switch handlers if / if necessary).

One of the biggest problems with callbacks (and even the code above) is type safety when using them. Many callbacks will accept a void * pointer, commonly referred to as context , which can be any type of data / memory. This provides more flexibility, but can be problematic if your pointers leave you. For example, you don’t want to accidentally use what is actually struct * like char * (or int , for that matter) by assignment. You can convey much more than simple strings and integers - structures, unions, enumerations, etc. - all this can be conveyed. CCAN enter safe callbacks to help avoid unwanted ghosts (from / void * ) in doing so.

Again, this is a more simplified example, which is designed to give you an overview of one of the possible ways to use callbacks. Please take a look at the psuedo code, which is intended as an example only.

+4
source

IN C, callbacks are performed with function pointers.

One feature that you definitely want is a user context. Your code takes a void * pointer and makes it available to the callback function:

 void callback(..., void *ctx); void call_service_which_invokes_callback(..., void (*cb)(..., void *ctx), void *ctx); 

Thus, the callback can access any desired state without using global variables.

+3
source

C callbacks are implemented using function pointers. This may be useful for a starting point:

What is callback in C and how are they implemented?

Moreover,

http://www.newty.de/fpt/callback.html#howto

+2
source

Source: https://habr.com/ru/post/1309191/


All Articles