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 要求可变参数函数和非可变参数函数以不同方式调用,并在寄存器中传递一些形式参数(整数和浮点数不同的寄存器)。
我有一组函数需要在 运行 时分配以便按顺序调用。哪个函数指针进入哪个位置是通过编程确定的,例如:
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 要求可变参数函数和非可变参数函数以不同方式调用,并在寄存器中传递一些形式参数(整数和浮点数不同的寄存器)。