簡體   English   中英

為可變數量的參數的不同函數編寫通用包裝器

[英]Writing a generalized wrapper for different functions with variable number of arguments

我想為一堆函數編寫C ++包裝器,這些函數在功能上都相似。 但他們都有不同數量的參數。 例如(假設typeA,typeB等是不同的typedef類型):

typeA func1 (typeB b, typeC c);

typeA func2 (typeB b, typeD d, typeE e);

這些是我要為其編寫包裝器的函數(注意,它們都具有返回類型typeA和類型typeB的第一個參數)。 因此,我打算創建一個通用包裝器類,並將參數列表存儲在構造函數中。 我希望能夠在下面調用類似於“ func”的函數:

class wrapper {
  public:
    wrapper (/*args - a list of arguments, including 
               a pointer to the actual function, and 
               the remaining arguments depending 
               on the function. */);
    void func (typeB b, typeA &a);
}

因此,我想以這樣一種方式編寫func:它使用傳入構造函數的參數調用任何函數(func1或func2)。

我想知道是否可以將func1或func2視為具有可變數量的參數。 或者至少,如果在C ++中有一種方法,我可以輸入一個函數和一個參數列表並獲取eval(函數,argument_list)。

另一種方法是為每個函數編寫一個包裝器,我想避免但並不反對。 (此外,我不介意解決方案是否涉及到我不是使用包裝器類而是包裝器函數)

這是我在C語言中完成的操作,以包裝所有功能。 我希望它能幫助/啟發您。 主要限制是只能包裝用戶定義的函數,因為您必須修改函數的簽名。

我的解決方案使用va_arg結構。

#include <stdarg.h>
void * super_wrapper( void * (*fn)(), void * ret, int n, ...)
{
  va_list = my_list;
  va_start(my_list, n);
  ret = (*fn)(ret, n, my_list);
  va_end(my_list);
  return ret
}

包裝器的簽名使用指向您要執行的函數的指針,賦予該函數的指針以檢索您的返回值,調用該函數的參數數量,然后是您想要執行的函數的參數呼叫。

va_list是參數列表。 您可以使用va_start對其進行初始化。 va_start的第一個參數是要初始化的va_list。 第二個參數是當前函數的最后一個已知參數(在本例中為“ n”)。

現在,您將放置參數va_list而不是用戶定義函數中的省略號。

我有兩個例子:

double sum (int n, ...)
{
  int i;
  double res = 0;
  double tmp;
  va_list = my_list;
  va_start(my_list, n);
  for(i=0; i<n; i++)
  {
    tmp = va_arg(my_list, double);
    res += tmp;
  }
  va_end(my_list);
  return res;
}

void my_print(int n, ...)
{
  int i;
  va_list my_list;
  va_start(my_list, n);
  char * tmp;
  for(i=0; i<n; i++)
  {
    tmp = va_arg(my_list, char *);
    printf("%s ", tmp);
  }
  printf("\n");
  va_end(my_list);
}

我設法使用相同的包裝器來調用這兩個不同的函數,並對簽名和函數主體進行了一些修改。 關鍵是在參數和返回中,我只給出指針。 因此,我必須取消引用指針。

void * sum (void * ret, int n, va_list my_list)
{
  int i;
  double res = 0;
  double *tmp;
  for(i=0; i<n; i++)
  {
    tmp = va_arg(my_list, double);
    res += *tmp;
  }
  ret = &res;
  return ret;
}

void* my_print(int n, ...)
{
  int i;
  char ** tmp;
  for(i=0; i<n; i++)
  {
    tmp = va_arg(my_list, char **);
    printf("%s ", *tmp);
  }
  printf("\n");
  return ret;
}

現在,我可以在主程序中使用相同的包裝器函數來調用這兩個函數:

void main()
{
  double two = 2.0;
  double three = 3.0;
  double fifteen = 15.0;

  char *I, *am, *a, *great, *wrapper;
  I = malloc(sizeof(char) * 2);
  am = malloc(sizeof(char) * 3);
  a = malloc(sizeof(char)*2);
  great = malloc(sizeof(char) * 6;
  wrapper = malloc(sizeof(char) * 8);

  I = strcpy(I, "I\0");
  am = strcpy(am, "am\0");
  a = strcpy(a,"a\0");
  great = strcpy(great, "great\0");
  wrapper = strcpy(wrapper, "wrapper\0");

  void * ret;

  printf("Sum = %f\n", *( (double*)super_wrapper(sum, ret, 3, &two, &three, &fifteen) ) );
  super_wrapper(my_print, ret, 5, &I, &am, &a, &great, &wrapper);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM