Malloc是一组函数指针

时间:2015-12-06 07:05:31

标签: c arrays function-pointers

我有一系列需要在运行时分配的函数才能按顺序调用。哪个函数指针以编程方式确定哪个点,例如:

void ((drawFunctions*)(...))[0] = drawTriangle;
...
for(...)
    drawFunctions[i](...);

我想要malloc一个函数指针数组,因为直到运行时才知道需要多少个函数指针。你会怎么做?

2 个答案:

答案 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要求以不同方式调用可变参数函数和非可变函数,并在寄存器中传递一些形式参数(整数和浮点的不同寄存器)。