2011-09-09 58 views
0

我有一組函數被調用 例如:用不同數量和類型的參數調用函數的機制?

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*/ 

我已經定義下面的函數指針和參數調用任何上述功能:

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

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

我已定義的自定義結構調用所有功能:

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

我已經初始化結構如下基於id(在任何時候,只有上述功能的一個被稱爲):

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 } 
}; 

現在,在一個開關case語句我試圖調用任何的功能:

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"); 
} 

在實際情況下,參數寫入直到在初始化結構中其地址將被賦予適當的數據類型的存儲器位置。

但是我面臨的問題是在調用函數時要傳遞/返回的參數的數據類型爲w.r.t。那麼是否有這種設置的機制,可以根據任何數據類型的參數數量來調用任何函數。

欣賞這方面的幫助。

+1

你肯定C是這個正確的語言? –

+0

不幸的是我不得不爲此使用C語言。 – Navaneet

+1

我沒有詳細閱讀,但將'int'變成'void *'來回肯定不是一個好主意。他們可能有不同的寬度(例如,他們有amd64)。如果你必須這樣做,總是使用'intptr_t'。 –

回答

1

我讀了各種各樣的功能,也許starting here。他們會讓你做你想做的。然後我會重寫所有的函數,以便它們總是傳遞可變參數,並且可能總是返回值,在void*中。

如果您使用了可變參數方案,您可能需要一個函數:我沒有仔細閱讀您的代碼,以確保這一點。那麼你可以通過(int) id作爲第一個參數來明確告訴函數做什麼以及如何做。然後

你的聲明看起來像(未經測試)這樣的:

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

和你一樣確定指標(未經測試)這樣的:

#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

謝謝皮特的建議。但我不能改變函數,基本上我需要一種機制,通過這種機制,我可以調用任何一個函數的參數被放入一個定義的內存位置,然後用適當的類型轉換來讀取它們,然後執行函數並放置結果(if任何)到另一個定義的內存位置(通過適當的類型轉換)。 – Navaneet

+1

你不能改變它們,但你可以把它們包裝起來,以使它們適合一個函數sinature方案。 – glglgl

相關問題