更优雅的方式将两个结构传递给C中的回调函数

时间:2014-04-03 13:10:34

标签: c pointers struct callback

假设我有两个typedef结构,我在程序中不断使用它来跟踪几件事情。

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

这是最优雅的解决方案吗?我可以用不同/更有效的方式“打开”结构吗?

感谢您的回答。

1 个答案:

答案 0 :(得分:1)

好吧,一个结构非常好,但是看到你传递指向结构的指针时,你也可以使用一个void指针数组。
不确定你是否愿意,因为它确实会造成混乱的代码,但仅作为一个例子:

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

请注意,如果要取消引用它们, do 需要转换void指针,否则,编译器会抛出错误,或者在某些边缘情况下可能会得到未定义的行为(即执行{ {1}}宏观事物) 但是,在这里使用数组的一个主要缺点是你必须知道哪个索引包含哪种类型,所以为了你自己:坚持offsetof

请注意,如果这是您的代码,则将指向本地变量的指针传递给struct函数。一旦register_callback函数返回,该局部变量就不再存在,并且传递给init_module的指针指向“不再是”的内存(即,包装器可能很好走了)。也要厌倦了。