找到你要的答案

Q:setup a series function pointers and callbacks in c

Q:设置一系列的回调函数指针,在C

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: Examples, hints and tips, please

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.

我读了一些不同的回答对函数指针作为回调,但我仍然有一些麻烦,实施它自己。

这样的问题:C中函数指针如何工作?

这理解为:typedef函数指针在C:的例子,提示和技巧,请

还有其他几个。

我不知道这是不是最好的方法。

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);

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)                     { //...}

目前我得到这样的警告:

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指针类型void*指针可以指向任何东西,甚至是什么?

我想概括函数指针,这样我就可以使用一个指针原型来处理所有的设置代码。从代码不工作,我知道我去它的错误的方式,并希望修复。

也许有一些指针的功能结构,但是我不确定ATM。

answer1: 回答1:

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;
}

我可以编译gcc a.c”下面的代码没有警告/错误。你确定你的回调函数作为“int FN(void *,void *)”。所以你的回调函数应该为“int FN实施(void* p,void * q){ }”

我改变功能”fixed_update”变成“int fixed_update(void *,void * B){ }”来匹配你的回调函数void误差定义。

希望对你有帮助。

#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;
}
answer2: 回答2:

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.

经过最初的评论和一些研究,我发现了一个行之有效的系统。下面是它的结构。

函数指针结构

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 函数指针结构. 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);

然后将正确的地址传递给服务器函数,然后在客户端代码中调用它需要的函数。

我希望这是能够帮助别人,如果他们遇到这样的事情在未来。

c  pointers  callback  function-pointers