C 如何通过调用堆栈传递函数指针?
我不确定我是否有这个问题的最佳标题,请随意改进 如果我有C 如何通过调用堆栈传递函数指针?,c,C,我不确定我是否有这个问题的最佳标题,请随意改进 如果我有 typedef void (*VoidFunction)(void); 然后是一系列适合这种类型的函数,我可以编写一种“事务”包装函数,类似于: void doTransaction(VoidFunction function) { doSomePreambleWork(); function(); doSomePostambleWork(); } // ????? I'm not sure how i'd t
typedef void (*VoidFunction)(void);
然后是一系列适合这种类型的函数,我可以编写一种“事务”包装函数,类似于:
void doTransaction(VoidFunction function)
{
doSomePreambleWork();
function();
doSomePostambleWork();
}
// ????? 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();
}
如果我有一系列函数采用单个int参数,我可以重复:
typedef void (*VoidOneIntFunction)(int a);
void doTransactionOneInt(VoidFunctionOneInt function, int a)
{
doSomePreambleWork();
function(a);
doSomePostambleWork();
}
离开返回类型的问题(iow,假设返回类型为void),是否可以将此模式泛化,这样我只需编写一个包装函数,比如:
void doTransaction(VoidFunction function)
{
doSomePreambleWork();
function();
doSomePostambleWork();
}
// ????? 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();
}
我不确定如何键入传递的函数
就像在其他任何地方声明函数指针一样:
void doTransactionGeneric(void (*function)(void), ...)
我不知道该怎么称呼它
就像你已经做的那样:
function();
如果您想使用
..
语法,即可变参数,则可以使用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();
}
这里有一个建议
假设您有多个功能(如您的问题中所述):
让我们定义类型枚举(我们不必使用枚举,但这更能说明问题):
然后,假设我们有一些通用处理器。我们需要提供函数类型、函数指针和参数:
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);
}
查看
标题。解决方法是使用可变参数列表。@Will我不认为这是OP所要求的。我希望得到比这些答案更“元”的东西。也许用C是不可能的。我想我可能会以某种方式弄乱堆栈,用调用堆栈的其余部分神奇地调用调用堆栈的第一个参数(已知为函数)(如果这样声明函数
,则无法将可变参数传递给doTransactionGeneric()
本身并将其传递给指定的函数。
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);
}