Evet yapabilirsin, ama bu biraz çirkin ve en fazla sayıda argümanı bilmek zorundasın. Ayrıca, argümanların x86 (örneğin, PowerPC) gibi yığına aktarılmadığı bir mimarideyseniz, "özel" türlerin (double, floats, altivec vb.) Kullanılıp kullanılmadığını ve böylece, onlarla uygun şekilde başa çıkmak. Çabuk acı verici olabilir, ancak x86 kullanıyorsanız veya orijinal işlevin iyi tanımlanmış ve sınırlı bir çevresi varsa, işe yarayabilir.
Hala bir hack olacak , hata ayıklama amacıyla kullanın. Yazılımınızı bunun üzerine kurmayın. Her neyse, işte x86 üzerinde çalışan bir örnek:
#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;
}
Herhangi bir nedenle va_arg ile şamandıra kullanamazsınız, gcc bunların ikiye dönüştürüldüğünü ancak programın çöktüğünü söylüyor. Bu tek başına bu çözümün bir saldırı olduğunu ve genel bir çözüm olmadığını gösterir. Örneğimde maksimum argüman sayısının 8 olduğunu varsaydım, ancak bu sayıyı artırabilirsiniz. Sarılı işlev yalnızca tamsayılar da kullandı, ancak her zaman tamsayılara aktarıldığından diğer 'normal' parametrelerle aynı şekilde çalışır. Hedef işlev türlerini bilecek, ancak ara paketleyicinizin bilmesine gerek yoktur. Sarıcı ayrıca doğru işlev argümanlarını bilmek zorunda değildir, çünkü hedef işlev bunu da bilir. Yararlı bir iş yapmak için (sadece aramayı kaydetmek hariç), muhtemelen her ikisini de bilmek zorunda kalacaksınız.