いくつかの入力に基づいて呼び出したい関数があります。関数ごとに引数の数が異なります。言い換えると、
if (strcmp(str, "funcA") == 0) funcA(a, b, c);
else if (strcmp(str, "funcB") == 0) funcB(d);
else if (strcmp(str, "funcC") == 0) funcC(f, g);
これは少しかさばり、保守が困難です。理想的には、これらは可変個引数関数(たとえば、printfスタイル)であり、varargsを使用できます。しかし、そうではありません。したがって、cdecl呼び出し規約を利用して、パラメーターでいっぱいの構造体を介してスタックを詰め込んでいます。それを行うためのより良い方法があるかどうか疑問に思います。これは厳密に社内(たとえば、単純なツール、単体テストなど)を対象としており、悪意のある攻撃を受ける可能性のある本番コードには使用されないことに注意してください。
例:
#include <stdio.h>
typedef struct __params
{
unsigned char* a;
unsigned char* b;
unsigned char* c;
} params;
int funcA(int a, int b)
{
printf("a = %d, b = %d\n", a, b);
return a;
}
int funcB(int a, int b, const char* c)
{
printf("a = %d, b = %d, c = %s\n", a, b, c);
return b;
}
int funcC(int* a)
{
printf("a = %d\n", *a);
*a *= 2;
return 0;
}
typedef int (*f)(params);
int main(int argc, char**argv)
{
int val;
int tmp;
params myParams;
f myFuncA = (f)funcA;
f myFuncB = (f)funcB;
f myFuncC = (f)funcC;
myParams.a = (unsigned char*)100;
myParams.b = (unsigned char*)200;
val = myFuncA(myParams);
printf("val = %d\n", val);
myParams.c = (unsigned char*)"This is a test";
val = myFuncB(myParams);
printf("val = %d\n", val);
tmp = 300;
myParams.a = (unsigned char*)&tmp;
val = myFuncC(myParams);
printf("a = %d, val = %d\n", tmp, val);
return 0;
}
出力:
gcc -o func func.c
./func
a = 100, b = 200
val = 100
a = 100, b = 200, c = This is a test
val = 200
a = 300
a = 600, val = 0