我有一系列需要在运行时分配的函数才能按顺序调用。哪个函数指针以编程方式确定哪个点,例如:
void ((drawFunctions*)(...))[0] = drawTriangle;
...
for(...)
drawFunctions[i](...);
我想要malloc一个函数指针数组,因为直到运行时才知道需要多少个函数指针。你会怎么做?
答案 0 :(得分:5)
typedef可能会让语法更具可忍性:
typedef void (*drawFunctionPointer)(void);
drawFunctionPointer *drawFunctions = malloc(sizeof(drawFunctionPointer) * numFunctions);
答案 1 :(得分:2)
首先,在C99中,variadic function应该至少有一个第一个非可变参数(如printf
有一个const char*fmt
第一个参数)。见stdarg(3)
然后,为了便于阅读,我会使用typedef
来声明函数签名,例如
typedef void drawfun_sigt (int, ...);
声明一个包含指向数组指针的变量:
drawfun_sigt** parr = NULL;
分配它(并处理失败):
size_t nbfun = somenumber();
parr = malloc(nbfun*sizeof(drawfun_sigt*));
if (!parr) { perror("malloc"); exit(EXIT_FAILURE); };
清除它(为了使行为更具可重复性,我不喜欢malloc
- ed数组中未初始化的元素;但是cmaster评论说valgrind会发现这些错误);您可以使用calloc
代替malloc
:
memset (parr, 0, nbfun*sizeof(drawfun_sigt*));
然后适当填写
extern void drawfunfoo(int, ....);
parr[0] = drawfunfoo;
当然,有很多方法可以获得函数地址。在POSIX系统(尤其是Linux)上,您甚至可以使用dlopen(3)和dlsym(3)
按其名称动态获取动态地址如果你的函数指针有一个完全未知的签名(即如果省略号...
在你的问题中意味着除了变量函数之外的东西),你应该使用libffi(或者,如果签名集是已知,使用union
函数指针)。请注意,C实现中的calling convention(以及ABI)可能(通常会)规定调用具有不同签名的函数的不同方法。例如,Linux的x86-64 ABI要求以不同方式调用可变参数函数和非可变函数,并在寄存器中传递一些形式参数(整数和浮点的不同寄存器)。