问题
I have a function that runs other functions, and these functions can have a variable number of arguments.
The parameter of this function is then passed to makecontext
, which attaches the function to a ucontext_t structure, but the problem is this function also takes variable number of arguments.
So my question is, how do I pass ellipsis argument obtained from a function to makecontext given that I can't change makecontext?
void run_function(void (*func), int argc, ...) {
va_list vl;
va_start(vl, argc);
makecontext(&ucontext, argc, ...);
va_end(vl);
}
回答1:
As pointed out in the comments by @nemequ, with a compiler like gcc
, it is possible to use a variadic macro. But
- The va_start() macro needs at least one parameter before the variable number of parameters: the last parameter is the name of the last argument before the variable argument list;
- The function func() passed to makecontext() is passed the variable number of parameters but not the argc parameter when it is called.
Hence, the macro wrapper forces argc as first parameter for func() to make it use va_start():
#include <ucontext.h>
#include <stdio.h>
#include <stdarg.h>
#define run_function(ucp, func, argc, ...) \
makecontext(ucp, func, (argc) + 1, argc, ##__VA_ARGS__)
typedef void (* ucfunc_t)(void);
void func1(int argc, ...)
{
va_list ap;
int param;
int i;
va_start(ap, argc);
printf("func1() running with %d parameters:\n", argc);
for (i = 0; i < argc; i ++) {
param = va_arg(ap, int);
printf("\t%d\n", param);
}
va_end(ap);
}
int main(void)
{
ucontext_t main_uc, uc1, uc2, uc3;
char stack1[4096], stack2[4096], stack3[4096];
getcontext(&uc1);
uc1.uc_link = &main_uc;
uc1.uc_stack.ss_sp = stack1;
uc1.uc_stack.ss_size = sizeof(stack1);
getcontext(&uc2);
uc2.uc_link = &uc1;
uc2.uc_stack.ss_sp = stack2;
uc2.uc_stack.ss_size = sizeof(stack2);
getcontext(&uc3);
uc3.uc_link = &uc2;
uc3.uc_stack.ss_sp = stack3;
uc3.uc_stack.ss_size = sizeof(stack3);
run_function(&uc1, (ucfunc_t)func1, 0);
run_function(&uc2, (ucfunc_t)func1, 5, 1, 2, 3, 4, 5);
run_function(&uc3, (ucfunc_t)func1, 2, 1, 2);
getcontext(&main_uc);
main_uc.uc_link = NULL;
swapcontext(&main_uc, &uc3);
return 0;
}
The previous example gives:
$ gcc ex1.c -o ex1
$ ./ex1
func1() running with 2 parameters:
1
2
func1() running with 5 parameters:
1
2
3
4
5
func1() running with 0 parameters:
来源:https://stackoverflow.com/questions/55769608/how-to-pass-ellipsis-argument-to-makecontext-which-also-accepts-ellipsis-argume