我有一个C函数,它接受变量实参,我需要用一个很长的实参列表来调用它,其中实参都遍历数组的元素。示例:
myFunction( A[0], B[0], A[1], B[1], A[2], B[2], A[3], B[3], ..... A[N], B[N] );
其中N通常为100-200。
我不希望每次我把N调大时都手动构造这个调用,我开始思考,有没有一种优雅的方法可以做到这一点?
我试过类似的东西:
i=0;
myFunction( A[i], B[i++], A[i], B[i++], A[i], B[i++], A[i], B[i++], ..... A[i], B[++] );
但这当然失败了。然而,它更可取的是,每当我把N调大时,我可以简单地一遍又一遍地复制同一行,而不必确保每个数组索引都是正确的,这是非常乏味的。
更改myFunction()不是一个选项。
我希望C有一种在运行中构建函数调用的方法,比如:
for( i = 0 ; i <= N ; i++ )
{
CONSTRUCT_CALL( myFunction, A[i], B[i] );
}
这正是我想要的,但这当然不是一个选择。
有什么可能更简单或更优雅的吗?
非常感谢。
没有标准的C方法可以做到这一点(在运行时合成可变调用)。但是
- 你可以使用libffi来处理这些问题(所以我推荐它)
- 您可以考虑构造调用的GCC特定内置
- 您可以对arity有一些固定的限制(例如500),并使用一些(shell、
awk
、Python…)脚本生成一些C文件,对500个案例执行switch
,每个arity一个 - 您可以考虑在运行时将一些C代码生成到
_gen123.c
中,将其编译为可动态加载的插件(例如,在Linux上派生一些gcc -shared -fPIC -Wall -O _gen123.c -o _gen123.so
命令),然后加载该插件(在Linux或Posix上使用dlopen(3)) - 您可能会考虑一些即时编译库(例如libjit、llvm、GNU闪电、asmjit…)
当然,在一个调用中要避免多个i++
。避免不明确的行为,因为坏事可能发生。
您的设计中有一些非常糟糕的地方。
重写您的myFunction
,使其使用两个数组(A和B),然后使用数字索引。
调用这样一个函数的简短示例:
int A[100];
int B[100];
int c = myFunction(A, B, 100);
myFunction
:的一种可能实现
int myFunction(int* A, int* B, int count)
{
int result = 0;
for(int j = 0; j < i; j++)
result += A[j] + B[j]*2;
return result;
}