在C中向回调函数传递两个结构的更优雅的方法

在C中向回调函数传递两个结构的更优雅的方法,c,pointers,struct,callback,C,Pointers,Struct,Callback,假设我有两个typedef'd结构,我经常在程序中使用它们来跟踪一些事情 typedef struct { int64_t data; } Struct_1 typedef struct { int32_t data; } Struct_2 我需要注册一个回调函数,在这里我可以传递一些用户数据: static int callback_function(void *user_data); 所以我考虑使用一个结构来传递两个结构: typedef struct { Str

假设我有两个typedef'd结构,我经常在程序中使用它们来跟踪一些事情

typedef struct {
   int64_t  data;
} Struct_1

typedef struct {
   int32_t  data;
} Struct_2
我需要注册一个回调函数,在这里我可以传递一些用户数据:

static int callback_function(void *user_data);
所以我考虑使用一个结构来传递两个结构:

typedef struct {
   Struct_1 *struct_1;
   Struct_2 *struct_2;
} Struct_wrapper;

init_module(Struct_1 *struct_1, Struct_2 *struct_2) {

Struct_wrapper struct_wrapper;
struct_wrapper.struct_1 = struct_1;
struct_wrapper.struct_2 = struct_2;

register_callback(callback_function, &struct_wrapper);
}
回调函数以这种方式展开结构:

static int callback_function(void *user_data) {

Struct_wrapper *struct_wrapper;
Struct_1 *struct_1;
Struct_2 *struct_2;

struct_wrapper = user_data;

struct_1 = struct_wrapper->struct_1;
struct_2 = struct_wrapper->struct_2;

process_data1(struct_1->data);
process_data2(struct_2->data);

return 0;
}
这是最优雅的解决方案吗?我能否以不同/更有效的方式“展开”结构


谢谢您的回答。

好吧,结构非常好,但是当您传递指向结构的指针时,您也可以使用一组空指针。
不确定您是否愿意,因为这确实会导致代码混乱,但举个例子:

init_module(Struct_1 *struct_1, Struct_2 *struct_2)
{
    void *wrapper[2] = {
        (void *) struct_1,
        (void *) struct_2
    };
    //to access them again:
    *((Struct_1 *)wrapper[0]).data = 123;
}
请注意,如果要取消引用空指针,则确实需要强制转换空指针。如果不这样做,编译器将抛出错误,或者在某些边缘情况下(即执行
offsetof
macro thingies)会出现未定义的行为。
不过,在这里使用数组的一个主要缺点是,您必须知道哪个索引包含什么类型,因此出于您自己的考虑:请坚持使用
结构


请注意,如果这是您的代码,则将指向局部变量的指针传递给
register\u回调
函数。一旦
init_module
函数返回,该局部变量就不再存在,传递到
register_callback
的指针指向“不再存在”的内存(即,包装器很可能会消失)。你也应该对此感到厌倦。

是的,这样的包装结构将是常见的方式。但如果这是实际的代码,那么
register\u callback(callback\u函数,&struct\u包装器)就有一个生存期问题,当您从
init_module()
返回时,
struct_wrapper
变量将消失/销毁。意见不适用于堆栈溢出。如果您的代码能够正常工作并满足您的需求,那么您就不会遇到此网站可以帮助解决的问题。如果你的代码有问题,你需要更有限地描述它。是的,你是对的。现在我明白了。那么推荐的方法是什么呢?init_module()的调用方是main()。我应该将包装器结构保留在main中,还是应该在模块文件中声明一个静态全局变量?感谢对结构包装器生存期的观察。关于在哪里声明包装结构有什么建议吗?init_module()的调用方是main()。我应该将包装器结构保留在main中,还是应该在模块文件中声明一个静态全局变量?我总是怀疑怎么做…@fazineroso:这真的取决于回调需要多长时间。如果答案是:只要程序运行,那么是的,包装器应该放在
main
函数中,但是,传递太多指针会让人厌烦,所以我不排除静态全局
静态结构{struct_1*s1;struct_2*s2;}*包装器或类似的东西谢谢Elias。在init_module()函数中声明结构包装器是静态的怎么样?这不也应该起作用吗?它优雅吗?@fazineroso:它可以工作,但它不优雅:一旦调用了
init_module
函数,包装器中的指针就不能更改,包装器的生命周期将从此与全局变量的生命周期相同。在这种情况下,我会选择全局变量