开发者

Mechanism to call functions with different number and type of parameters?

I have a set of functions to be called e.g.:

void void_func();                   /* id = 0 */
void void_func1(int);               /* id = 1 */
void void_func2(int, char *);       /* id = 2 */
void void_func3(short int);         /* id = 3 */

int int_func();                     /* id = 4 */            
int int_func1(int);                 /* id = 5 */
int int_func2(float);               /* id = 6 */
int int_func3(int, int *);          /* id = 7 */

char *char_func();                  /* id = 8 */
char *char_func1(int);              /* id = 9 */
char *char_func2(int, int);         /* id = 10*/

void enum_func(enum_t);             /* id = 11*/
enum_t enum_func1(int *, int);      /* id = 12*/
enum_t enum_func2();                /* id = 13*/

I have defined the following function pointers and parameters for calling any of the above functions:

typedef void * (*funcptr)();
typedef void * (*funcptr1)(void *);
typedef void * (*funcptr2)(void *, void *);

void * parameter1;
void * parameter2;
void * return_param;

I have defined a custom struct for calling all the functions:

typedef struct funcid {
    int id;
    funcptr f0;
    funcptr1 f1;
    funcptr2 f2;
    void * param1;
    void * param2;
    void * ret_param;
} func_id;

I have initialized the struct as below based on id (At any time only one of the above functions is called):

func_id func_str[] = {
/*  { id,       f0      ,       f1      ,       f2      ,           param1          ,       param2          ,           ret_param       } ,*/
    { 0 , &void_func    ,   NULL        ,   NULL        , (void *)parameter1        , (void *)parameter2    , (void *)return_param      } ,
    { 1 ,   NULL        , &void_func1   ,   NULL        , (int  *)parameter1        , (void *)parameter2    , (void *)return_param      } ,
    { 2 ,   NULL        ,   NULL        , &void_func2   , (int  *)parameter1        , (char *)parameter2    , (void *)return_param      } ,
    { 3 ,   NULL        , &void_func3   ,   NULL        , (short int *)parameter1   , (void *)parameter2    , (void *)return_param      } ,
    { 4 , &int_func     ,   NULL        ,   NULL        , (void *)parameter1        , (void *)parameter2    , (int  *)return_param      } ,
    { 5 ,   NULL        , &int_func1    ,   NULL        , (int  *)parameter1        , (void *)parameter2    , (int  *)return_param      } ,
    { 6 ,   NULL        , &int_func2    ,   NULL        , (float*)parameter1        , (void *)parameter2    , (int  *)return_param      } ,
    { 7 ,   NULL        ,   NULL        , &int_func3    , (int  *)parameter1        , (int  *)parameter2    , (int  *)return_param      } ,
    { 8 , &char_func    ,   NULL        ,   NULL        , (void *)parameter1        , (void *)parameter2    , (char *)return_param      } ,
    { 9 ,   NULL        , &char_func1   ,   NULL        , (int  *)parameter1        , (void *)parameter2    , (char *)return_param      } ,
    { 10,   NULL        ,   NULL        , &char_func2   , (int  *)parameter1        , (int  *)parameter2    , (char *)return_param      } ,
    { 11, &enum_func    ,   NULL        ,   NULL        , (enum_t *)parameter1      , (void *)parameter2    , (void *)return_param      } ,
    { 12,   NULL        ,   NULL        , &enum_func1   开发者_运维问答, (int  *)parameter1        , (int  *)parameter2    , (enum_t *)return_param    } ,
    { 13, &enum_func2   ,   NULL        ,   NULL        , (str1 *)parameter1        , (void *)parameter2    , (enum_t *)return_param    } 
};

Now in a switch case statement I am trying to call any of the functions:

printf("\nEnter Number of parameters of functions : ");
scanf("%d", ptr1);

printf("\nEnter whether the function has a return value (0/1) : ");
scanf("%d", &ret);

printf("\nWhich function to execute (function id): ");
scanf("%d", &var1);

if (*ptr1 > 0)
    printf("\nEnter the Parameters : \n");

func_id current_func;

for (i=0; i<13; i++){
    if (func_str[i].id == var1) {
        current_func = func_str[i];
        break;
    }
}

switch(*ptr1) {

    case 0: {
        if (ret == 1) {
            printf("\nEntering case 0\n");
            current_func.ret_param = (*current_func.f0)();
        }
        else {
            (*current_func.f0)();
        }
        break;
        }
    /* In actual case the parameters would be read from a memory location and the address of that can be stored in parameter1 */
    case 1: {
        printf("\nEnter Parameter 1: ");
        scanf("%d", parameter1); 
        printf("\nParameter 1 = %d\n",*(int *)parameter1);
        if (ret == 1) {
            current_func.ret_param = (*current_func.f1)(current_func.param1);
        }
        else {
            (*current_func.f1)(current_func.param1);
        }
        break;
        }
    /* In actual case the parameters would be written in a memory location and the address of that can be stored in parameter1 and parameter2 */
    case 2: { 
        printf("\nEnter Parameter 1: ");
        scanf("%d", parameter1);
        printf("\nEnter Parameter 2: ");
        scanf("%d", parameter2);
        if (ret == 1) {
            current_func.ret_param = (*current_func.f2)(current_func.param1, current_func.param2);
            printf("\nReturned parameter : current_func.ret_param = %d", *(int *)current_func.ret_param);
        }
        else {
            (*current_func.f2)(current_func.param1, current_func.param2);
        }
        break;
        }
    default:
        printf("ERROR");
}

In actual case the parameters is written on to a memory location whose address would be assigned with appropriate data-type in the initializing structure.

But the problem I am facing is w.r.t to the data-types of the parameters to be passed/returned while calling the functions. So is there any mechanism for such kind of setup where one can be able to call any function based on number of parameters of any data-type.

Appreciate the help in this regard.


I'd read up on variadic functions, perhaps starting here. They'll let you do what you want. Then I would rewrite all of the functions so that they always pass the variable arguments, and maybe always return values, in void* .

If you used the variable-arguments scheme, you might need only one function: I didn't read your code closely enough to be sure about this. Then you might pass (int) id as the first argument to tell the function unequivocally what to do and how.

Your declaration would then look like (untested) this:

#include <stdarg.h>
void *
the_func ( int id, void *arg1, ... );

and your defintion like (untested) this:

#include <stdarg.h>
void *
the_func ( int id, void *arg1, ... ) {
  #define max_args 10;   
  int i = 0;
  void *args[max_args];
  va_list arglist;
  ...
  // extract incoming args
  va_start( arglist, id );
  while ( i++ < sizeof( args )-1 ) {
    args[i] = va_arg( arglist, void* );
  }
  va_end( arglist );
// now we have all arguments in args[]
    switch ( id ) {  // dispatch on id
    case ....
    } 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜