2

我不确定我是否有这个问题的最佳标题,请随时改进。

如果我有

typedef void (*VoidFunction)(void);

然后是适合这种类型的一系列函数,我可以编写一种“事务”包装函数,如下所示:

void doTransaction(VoidFunction function)
{
    doSomePreambleWork();
    function();
    doSomePostambleWork();
}

如果我有一系列接受单个 int 参数的函数,我可以清洗-冲洗-重复:

typedef void (*VoidOneIntFunction)(int a);
void doTransactionOneInt(VoidFunctionOneInt function, int a)
{
    doSomePreambleWork();
    function(a);
    doSomePostambleWork();
}

留下返回类型的问题(iow,假设返回类型为 void),是否可以泛化这种模式,这样我只需要编写一个包装函数,例如:

// ????? I'm not sure how i'd type the passed function
void doTransactionGeneric(void * function, ...)
{
    doSomePreambleWork();
    function(); // ????? and i don't know how i'd go about calling it...
    doSomePostambleWork();
}
4

3 回答 3

2

如果要使用...称为可变参数的语法,则可以使用va_list来访问参数列表,例如:

#include <stdarg.h>

typedef void (*VoidArgsFunction)(va_list args);

void doTransactionGeneric(VoidArgsFunction function, ...)
{
    doSomePreambleWork();

    va_list args;
    va_start(args, function);
    function(args);
    va_end(args);

    doSomePostambleWork();
}

在被调用函数内部,它可以根据需要va_arg()从 访问各个参数值va_list​​,例如:

#include <stdarg.h>

void someFunction(va_list args)
{
    int param1 = va_arg(args, int);
    char *param2 = va_arg(args, char*);
    ...
}

doTransactionGeneric(&somefunction, 12345, "Hello World");
于 2013-04-24T17:36:37.107 回答
0

我不确定如何输入传递的函数

就像您在其他任何地方声明一个函数指针一样:

void doTransactionGeneric(void (*function)(void), ...)

而且我不知道该怎么称呼它...

就像你已经做过的那样:

function();
于 2013-04-24T17:27:47.960 回答
0

这是一个建议。

假设您有几个功能(如您的问题):

typedef void (*VoidFunction)(void);
typedef void (*VoidFunctionOneInt)(int);
// we can add more

让我们定义类型枚举(我们不必使用枚举,但这更能说明问题):

typedef enum
{
   e_fn_void,     // void return, no args
   e_fn_void_int, // void return, one int
                  // we can add more...
} void_function_kind_t;

然后,假设我们有一些通用处理器。我们需要提供函数的类型、函数指针和参数:

void some_generic_function(void_function_kind_t kind, void *fn, ...)
{
   va_list args;
   va_start(args, fn);

   // here - make a call
   switch (kind)
   {
   case e_fn_void:
        // no arguments
        ((VoidFunction)fn)();
        break;
   case e_fn_void_int:
        {
           int arg0 = va_arg(args,int);
           ((VoidFunctionOneInt)fn)(arg0);
        }
        break;
   default: // error - unsupported function type
        break;
   }

   va_end(args);
}
于 2013-04-24T17:43:40.927 回答