是的,您可以执行此操作,但这有点难看,您必须知道最大数量的参数。此外,如果您所处的体系结构没有像x86那样在堆栈上传递参数(例如PowerPC),则必须知道是否使用了“特殊”类型(双精度,浮点型,altivec等),以及是否因此,请相应地处理它们。可能很快就会很痛苦,但是如果您使用的是x86,或者原始功能的边界明确且受限制,则可以正常使用。
它仍然是一个hack,用于调试目的。不要围绕此构建软件。无论如何,这是x86上的一个有效示例:
#include <stdio.h>
#include <stdarg.h>
int old_variadic_function(int n, ...)
{
va_list args;
int i = 0;
va_start(args, n);
if(i++<n) printf("arg %d is 0x%x\n", i, va_arg(args, int));
if(i++<n) printf("arg %d is %g\n", i, va_arg(args, double));
if(i++<n) printf("arg %d is %g\n", i, va_arg(args, double));
va_end(args);
return n;
}
int old_variadic_function_wrapper(int n, ...)
{
va_list args;
int a1;
int a2;
int a3;
int a4;
int a5;
int a6;
int a7;
int a8;
/* Do some work, possibly with another va_list to access arguments */
/* Work done */
va_start(args, n);
a1 = va_arg(args, int);
a2 = va_arg(args, int);
a3 = va_arg(args, int);
a4 = va_arg(args, int);
a5 = va_arg(args, int);
a6 = va_arg(args, int);
a7 = va_arg(args, int);
va_end(args);
return old_variadic_function(n, a1, a2, a3, a4, a5, a6, a7, a8);
}
int main(void)
{
printf("Call 1: 1, 0x123\n");
old_variadic_function(1, 0x123);
printf("Call 2: 2, 0x456, 1.234\n");
old_variadic_function(2, 0x456, 1.234);
printf("Call 3: 3, 0x456, 4.456, 7.789\n");
old_variadic_function(3, 0x456, 4.456, 7.789);
printf("Wrapped call 1: 1, 0x123\n");
old_variadic_function_wrapper(1, 0x123);
printf("Wrapped call 2: 2, 0x456, 1.234\n");
old_variadic_function_wrapper(2, 0x456, 1.234);
printf("Wrapped call 3: 3, 0x456, 4.456, 7.789\n");
old_variadic_function_wrapper(3, 0x456, 4.456, 7.789);
return 0;
}
由于某些原因,您不能将浮点数与va_arg一起使用,gcc表示它们会转换为double值,但程序会崩溃。仅此一点就表明该解决方案是黑客,并且没有通用解决方案。在我的示例中,我假设参数的最大数量为8,但是您可以增加该数量。包装函数也只使用整数,但是它与其他“普通”参数的工作方式相同,因为它们始终转换为整数。目标函数将知道它们的类型,但是您的中间包装器不需要。包装程序也不需要知道正确数量的参数,因为目标函数也可以知道。为了做有用的工作(除了仅记录呼叫),您可能必须同时知道两者。