gpt4 book ai didi

c - C 回调函数的参数 : va_list, 和省略号哪个更好?

转载 作者:行者123 更新时间:2023-12-04 10:49:42 25 4
gpt4 key购买 nike

我的图书馆提供了一个回调点,我的图书馆用户可以在其中注册以获取信息。回调的一般形式是 int 后跟各种参数,其类型取决于 int 值。因此,我定义了回调类型和设置它的函数如下。

typedef void (* callback_func_t)(int type, ...);
void set_callback_func(callback_func_t callback);

在我的库中,我一直在调用这个函数,作为用户设置函数,或者我提供的默认函数。它有效。

现在,我想添加一个间接级别,以便能够调用多个已注册的回调。麻烦的是,我的内部回调函数仍然采用省略号参数,也必须使用省略号调用回调函数。因此,我的内部函数必须解释 type,从 va_list 中解压参数并将它们作为参数提供给 callbacj 函数。

void internal_callback(int type, ...) {
va_list args;
va_start(args, type);
switch (type) {
case 0: call_callback(type, va_arg(args, int)); break;
// ...
}
va_end(args);
}

但是,在用户实现回调时,也会有相同的va_list用法,以及参数的解释,根据type的值。解决方案是直接将va_list作为参数传递给回调函数,使内部回调函数的实现一目了然。

typedef void (* callback_func_t)(int type, va_list args);

我的问题是:定义一个以 va_list 作为参数的回调函数类型是好的做法吗?我可以像上面那样定义我的回调函数类型,但是与顶部的定义相比有什么优缺点?

最佳答案

我假设存在有限数量且已知的类型?如果是这样,为什么不使用枚举和 union 来实现某种级别的类型安全,这也会顺便解决您的问题:

enum callback_arg_type { INT_ARG, DOUBLE_ARG, VECTOR_ARG };

union callback_arg
{
int as_int;
double as_double;
struct { double x, y, z; } as_vector;
};

typedef void (*callback_func_t)(
enum callback_arg_type type, union callback_arg arg);

根据参数大小的不同,传递指针可能是个好主意。您还可以提供一些宏来为回调调用提供更好的语法,但如果它们只从您的库中调用,则可能不值得这样做:

union callback_arg arg = { .as_int = 42 };
callback_fn(INT_ARG, arg);

本身就很短。

关于c - C 回调函数的参数 : va_list, 和省略号哪个更好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4033899/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com