그렇습니다, 그러나 그것은 추악한 일이며 최대한 많은 수의 주장을 알아야합니다. 또한 x86과 같이 스택에 인수가 전달되지 않는 아키텍처를 사용하는 경우 (예 : PowerPC) "특수"유형 (double, float, altivec 등)이 사용되는지 여부와 따라서 그에 따라 처리하십시오. 빨리 고통 스러울 수 있지만 x86을 사용 중이거나 원래 기능에 경계가 잘 정의되어 있고 제한이있는 경우 작동 할 수 있습니다.
여전히 핵이 될 것이므로 디버깅 목적으로 사용하십시오. 주변에 소프트웨어를 구축하지 마십시오. 어쨌든, 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와 함께 float를 사용할 수 없으며 gcc는 double로 변환되지만 프로그램이 충돌한다고 말합니다. 이것만으로는이 솔루션이 해킹이며 일반적인 솔루션이 없음을 보여줍니다. 내 예에서는 최대 인수 수가 8이라고 가정했지만 그 수를 늘릴 수 있습니다. 랩핑 된 함수는 정수만 사용했지만 항상 다른 정수로 캐스트되므로 다른 '정상'매개 변수와 동일한 방식으로 작동합니다. 대상 함수는 유형을 알지만 중간 래퍼는 필요하지 않습니다. 래퍼는 또한 대상 함수가이를 알기 때문에 올바른 수의 인수를 알 필요가 없습니다. 유용한 작업을 수행하려면 (통화 기록 만 제외하고) 둘 다 알고 있어야합니다.