Ja, Sie können es tun, aber es ist etwas hässlich und Sie haben die maximale Anzahl von Argumenten kennen. Wenn Sie sich in einer Architektur befinden, in der die Argumente nicht wie der x86 (zB PowerPC) auf dem Stack übergeben werden, müssen Sie wissen, ob "spezielle" Typen (double, floats, altivec usw.) verwendet werden und ob Behandle sie dementsprechend. Es kann schnell schmerzhaft sein, aber wenn Sie auf x86 sind oder wenn die ursprüngliche Funktion einen gut definierten und begrenzten Umfang hat, kann es funktionieren. Es wird noch ein Hack sein, verwenden Sie es Zweck für das Debuggen. Baue dir dafür keine Software. Wie auch immer, hier ist ein funktionierendes Beispiel auf 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 kann man nicht schwimmt mit va_arg verwenden, gcc, sagt sie, aber die Programmabstürze sind umgewandelt zu verdoppeln. Das allein zeigt, dass diese Lösung ein Hack ist und dass es keine allgemeine Lösung gibt. In meinem Beispiel nahm ich an, dass die maximale Anzahl von Argumenten 8 war, aber Sie können diese Zahl erhöhen. Die umbrochene Funktion verwendet ebenfalls nur ganze Zahlen, aber sie funktioniert auf die gleiche Weise mit anderen 'normalen' Parametern, da sie immer in Ganzzahlen umgewandelt werden. Die Zielfunktion kennt ihre Typen, aber Ihr intermediärer Wrapper muss dies nicht tun. Der Wrapper muss auch nicht die richtige Anzahl von Argumenten kennen, da die Zielfunktion sie auch kennt. Um nützliche Arbeit zu tun (außer nur den Anruf zu protokollieren), müssen Sie wahrscheinlich beide wissen.
ehrfürchtige Frage - zum Glück kann ich eine vFunc Überlastung hinzufügen, die eine va_list nimmt. Danke fürs Schreiben. – Gishu