Reputation: 1917
I've read a few different SO answers on function pointers as callbacks but I am still having some trouble implementing it myself.
Questions like this: How do function pointers in C work?
and this: Understanding typedefs for function pointers in C
and a few others.
I am not sure if this is the best way to go about it.
file.h
typedef int (*reg_callback)(void*, void*); //generalize a bit?
int register_created(reg_callback cb);
int register_fixed_update(reg_callback cb);
int register_variable_update(reg_callback cb);
int register_render(reg_callback cb);
int register_pased(reg_callback cb);
int register_resume(reg_callback cb);
int register_resize(reg_callback cb);
int register_quit(reg_callback cb);
int init_engine(int width, int height, char *title, double fps);
//prototypes of functions that I need callbacks for atm maybe more soon
void created(void);
void fixed_update(void);
void variable_update(void);
void render(double alpha);
void paused(void);
void resumed(void);
void resized(int width, int height);
void quit(void);
file.c
static int register_callback_function(int c_type, reg_callback cb)
{
int success = -1;
switch(c_type)
{
case 000000:
printf("registering fixed update\n");
break;
case 000001:
printf("registering variable update\n");
break;
case 000002:
printf("registering render\n");
break;
case 000003:
printf("registering pause\n");
break;
case 000004:
printf("registering resume\n");
break;
case 000005:
printf("registering resize\n");
break;
case 000006:
printf("registering quit\n");
break;
default:break;
}
return success;
}
int register_fixed_update(reg_callback cb) { return register_callback_function(000000, cb); };
int register_variable_update(reg_callback cb) { return register_callback_function(000001, cb); };
int register_render(reg_callback cb) { return register_callback_function(000002, cb); };
int register_pased(reg_callback cb) { return register_callback_function(000003, cb); };
int register_resume(reg_callback cb) { return register_callback_function(000004, cb); };
int register_resize(reg_callback cb) { return register_callback_function(000005, cb); };
int register_quit(reg_callback cb) { return register_callback_function(000006, cb); };
int register_created(reg_callback cb) { return register_callback_function(000007, cb); };
void created(void) { //call create callback func }
void fixed_update(void) { //call fixed update callback func}
void variable_update(void) { //...}
void render(double alpha) { //...}
void paused(void) { //...}
void resumed(void) { //...}
void resized(int width, int height) { //...}
void quit(void) { //...}
currently I am getting a warning like these:
warning: incompatible pointer types passing 'void (void)' to parameter of
type 'reg_callback' (aka 'int (*)(void *, void *)') [-Wincompatible-pointer-types]
register_created(created);
^~~~~~~
note: passing argument to parameter 'cb' here
int register_created(reg_callback cb);
incompatibile pointer types but I though that void* pointers could point to anything, even nothing?
I wanted to generalize the function pointer so that I could just use the one pointer prototype to handle all this setup code. From the code not working I know I am going about it the wrong way and would like to fix that.
maybe have a struct with some pointer to functions but I am not sure atm.
Upvotes: 2
Views: 91
Reputation: 1917
After the initial comments and some more research I found a system that worked pretty well. Here's how it's structured.
function pointer struct
server.c
typedef struct
{
void (*init_fnc_ptr)(void);
void (*fixed_update_fnc_ptr)(void);
void (*variable_update_fnc_ptr)(void);
void (*render_fnc_ptr)(double alpha);
void (*paused_fnc_ptr)(void);
void (*resumed_fnc_ptr)(void);
void (*resized_fnc_ptr)(int width, int height);
void (*quit_fnc_ptr)(void);
} lfcyc_fnc_ptr;
lfcyc_fnc_ptr* lfc_f;
init() { lfc_f->init_fnc_ptr(); }
void fixed_update(void) { lfc_f->fixed_update_fnc_ptr(); }
//etc
and a function that takes one of these function pointer struct. In the client code I import the proper header and then initialize it;
lfcyc_fnc_ptr* funcs = (lfcyc_fnc_ptr *)malloc(sizeof(lfcyc_fnc_ptr));
funcs->init_fnc_ptr = &initialized;
funcs->fixed_update_fnc_ptr = &fixed_update;
funcs->variable_update_fnc_ptr = &variable_update;
funcs->render_fnc_ptr = &render;
funcs->paused_fnc_ptr = &paused;
funcs->resumed_fnc_ptr = &resumed;
funcs->resized_fnc_ptr = &resized;
funcs->quit_fnc_ptr = &quit;
register functions(funcs);
//work
free(funcs);
this then passes the correct address to the server function then it can call the functions that it needs to in the client code.
I hope this is able to assist someone if they encounter something like this in the future.
Upvotes: 1
Reputation: 51
I can compile "gcc a.c" the follow code without warning/error. You defined you call back function as "int fn(void *, void *)". So your call back function should implement as "int fn(void *p, void *q){}"
I change the function "fixed_update" into "int fixed_update(void *a, void *b) {}" to match you callback function define to void error.
I hope it will help you.
#include <stdio.h>
typedef int (*reg_callback)(void*, void*);
static int register_callback_function(int c_type, reg_callback cb)
{
int success = -1;
switch(c_type)
{
case 000000:
printf("registering fixed update\n");
break;
default:
break;
}
return success;
}
int register_fixed_update(reg_callback cb) {
return register_callback_function(000000, cb);
};
int fixed_update(void *a, void *b) {
}
int main()
{
register_fixed_update(fixed_update);
return 0;
}
Upvotes: 1