Có, bạn có thể làm điều đó, nhưng nó có phần xấu xí 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 mà các đối số không được truyền trên stack như x86 (ví dụ, PowerPC), bạn sẽ phải biết nếu các loại "đặc biệt" (đôi, nổi, altivec vv) được sử dụng và nếu vì vậy, đối phó với chúng cho phù hợp. Nó có thể gây đau đớn một cách nhanh chóng nhưng nếu bạn đang ở trên x86 hoặc nếu chức năng ban đầu có chu vi được xác định rõ ràng 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ụ làm việc 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;
}
Đối với một số lý do, bạn không thể sử dụng phao nổi với va_arg, gcc nói rằng họ đang chuyển đổi sang gấp đôi nhưng chương trình bị treo. Điều đó một mình chứng minh rằng giải pháp này là một hack và rằng không có giải pháp chung. Trong ví dụ của tôi, tôi giả định rằng số lượng đối số tối đa là 8, nhưng bạn có thể tăng số đó. Hàm bọc cũng chỉ sử dụng các số nguyên nhưng nó hoạt động theo cùng một cách với các tham số 'bình thường' khác vì chúng luôn luôn truyền đến số nguyên. Hàm mục tiêu sẽ biết 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 số lượng đối số phù hợp 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ừ việc chỉ ghi nhật ký cuộc gọi), bạn có thể sẽ phải biết cả hai.
tuyệt vời câu hỏi - may mắn thay tôi có thể thêm một tình trạng quá tải vFunc mà phải mất một va_list. Cảm ơn vì đăng. – Gishu