Có bạn có thể làm điều đó, nhưng nó hơi xấu và bạn phải biết số lượng đối số tối đa. Hơn nữa, nếu bạn đang ở trên một kiến trúc nơi các đối số không được truyền trên ngăn xếp như x86 (ví dụ: PowerPC), bạn sẽ phải biết liệu các loại "đặc biệt" (double, float, altivec, v.v.) có được sử dụng không và nếu vì vậy, đối phó với chúng cho phù hợp. Nó có thể bị đau nhanh chóng nhưng nếu bạn ở trên x86 hoặc nếu chức năng ban đầu có chu vi được xác định rõ và giới hạn, nó có thể hoạt động.
Nó vẫn sẽ là một hack , sử dụng nó cho mục đích gỡ lỗi. Đừng xây dựng phần mềm cho bạn. Dù sao, đây là một ví dụ hoạt động trên 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;
}
Vì một số lý do, bạn không thể sử dụng float với va_arg, gcc nói rằng chúng được chuyển đổi thành gấp đôi nhưng chương trình gặp sự cố. Điều đó một mình chứng tỏ rằng giải pháp này là một hack và không có giải pháp chung. Trong ví dụ của tôi, tôi giả sử rằng số lượng đối số tối đa là 8, nhưng bạn có thể tăng số lượng đó. Hàm được bọc cũng chỉ sử dụng các số nguyên nhưng nó hoạt động tương tự với các tham số 'bình thường' khác vì chúng luôn truyền sang các số nguyên. Hàm mục tiêu sẽ biết các loại của chúng nhưng trình bao bọc trung gian của bạn không cần. Trình bao bọc cũng không cần biết đúng số lượng đối số vì hàm mục tiêu cũng sẽ biết nó. Để thực hiện công việc hữu ích (ngoại trừ chỉ ghi nhật ký cuộc gọi), có lẽ bạn sẽ phải biết cả hai.