Ja, Sie können es tun, aber es ist etwas hässlich und Sie müssen die maximale Anzahl von Argumenten kennen. Wenn Sie sich in einer Architektur befinden, in der die Argumente nicht wie x86 (z. B. PowerPC) auf dem Stapel übergeben werden, müssen Sie außerdem wissen, ob und ob "spezielle" Typen (double, float, altivec usw.) verwendet werden Gehen Sie also entsprechend mit ihnen um. Es kann schnell schmerzhaft sein, aber wenn Sie auf x86 arbeiten oder wenn die ursprüngliche Funktion einen genau definierten und begrenzten Umfang hat, kann es funktionieren.
Es wird immer noch ein Hack sein , verwenden Sie es zum Debuggen. Erstellen Sie keine Software dafür. Hier ist ein funktionierendes Beispiel für 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;
}
Aus irgendeinem Grund können Sie Floats nicht mit va_arg verwenden. Laut gcc werden sie in double konvertiert, aber das Programm stürzt ab. Das allein zeigt, dass diese Lösung ein Hack ist und dass es keine allgemeine Lösung gibt. In meinem Beispiel habe ich angenommen, dass die maximale Anzahl von Argumenten 8 beträgt, aber Sie können diese Anzahl erhöhen. Die umschlossene Funktion verwendete ebenfalls nur Ganzzahlen, funktioniert jedoch genauso mit anderen 'normalen' Parametern, da diese immer in Ganzzahlen umgewandelt werden. Die Zielfunktion kennt ihre Typen, Ihr Zwischen-Wrapper muss dies jedoch nicht. Der Wrapper muss auch nicht die richtige Anzahl von Argumenten kennen, da die Zielfunktion dies auch weiß. Um nützliche Arbeit zu leisten (außer nur den Anruf zu protokollieren), müssen Sie wahrscheinlich beide kennen.