在C中向回调函数传递两个结构的更优雅的方法
假设我有两个typedef'd结构,我经常在程序中使用它们来跟踪一些事情在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 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
函数,包装器中的指针就不能更改,包装器的生命周期将从此与全局变量的生命周期相同。在这种情况下,我会选择全局变量