malloc 一个函数指针数组

Malloc an array of function pointers

我有一组函数需要在 运行 时分配以便按顺序调用。哪个函数指针进入哪个位置是通过编程确定的,例如:

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

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

typedef 可能会使语法更容易接受:

typedef void (*drawFunctionPointer)(void);
drawFunctionPointer *drawFunctions = malloc(sizeof(drawFunctionPointer) * numFunctions);

首先,在C99中,一个variadic function should have at least one first non-variadic argument (like printf has a const char*fmt first argument). See 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 编辑的数组中未初始化的元素;但是 cmaster commented that valgrind 会发现这些错误);你可以使用 calloc 而不是 malloc:

 memset (parr, 0, nbfun*sizeof(drawfun_sigt*));

然后适当填写

 extern void drawfunfoo(int, ....);
 parr[0] = drawfunfoo;

当然,获取函数地址的方法有很多种。在 POSIX 系统(特别是 Linux)上,您甚至可以使用 dlopen(3) and dlsym(3)

通过名称 动态地 获得这样的地址

如果您的函数指针具有完全未知的签名(即,如果省略号 ... 在您的问题中表示除可变参数函数之外的其他内容),您应该使用 libffi (or, if the set of signature is known, use a union of function pointers). Be aware that the calling convention (and the ABI) on your C implementation may (and often does) dictate different ways to call functions with different signature. For example the x86-64 ABI 作为 Linux 要求可变参数函数和非可变参数函数以不同方式调用,并在寄存器中传递一些形式参数(整数和浮点数不同的寄存器)。