gpt4 book ai didi

调用具有不同参数个数的 cdecl 函数

转载 作者:太空宇宙 更新时间:2023-11-04 04:58:12 25 4
gpt4 key购买 nike

我有希望根据某些输入调用的函数。每个函数都有不同数量的参数。换句话说,

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 样式)并且可以使用可变参数。但他们不是。因此,利用 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

最佳答案

我不会尝试用语言来解决这个极端情况,而是通过定义可变包装函数以更直接的方式来做到这一点。您通常可以使用宏来执行此操作:

#define WRAP_VARIADIC_2_ARG(FNAME, RETTYPE, ARGTYPE1, ARGTYPE2) \
(RETTYPE) wrapped_##FNAME(...) { \
va_list args; \
va_start(args, 2); \
(ARGTYPE1) arg1 = va_arg(args, (ARGTYPE1)); \
(ARGTYPE2) arg2 = va_arg(args, (ARGTYPE2)); \
va_end(args); \
return FNAME(arg1, arg2); \
}

以及用于其他 arg 计数的类似宏。然后,您调用:

WRAP_VARIADIC_2_ARG(funcA, int, int, int)
WRAP_VARIADIC_3_ARG(funcB, int, int, int, const char*)
WRAP_VARIADIC_1_ARG(funcC, int, int*)

这将定义一组具有以下签名的函数,您可以在调度函数中使用它们:

int wrapped_funcA(...)
int wrapped_funcB(...)
int wrapped_funcC(...)

这应该很简单。

关于调用具有不同参数个数的 cdecl 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2427794/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com