2013-04-23 45 views
1

我正在尋找通過指針傳遞一個可變數量的參數指向一個回調函數,也是由指針引用。有什麼辦法可以創建一個可以通過引用傳遞的參數列表嗎?將指針傳遞給C++中的可變參數?

例:

typedef struct MENUELEMENT 
{ 
    void* OK_func; void* OK_args; 
} menuElement_t; 

menuElement_t* curMenuElement; 

menuElement_t menu[] = 
{ 
    //First Menu Element 
    (void*)menuDisplayText, (void*)("Test", (char*)&lcdBuffer[0]) //menuDisplayText is a function that takes two arguments 
    //Second Menu Element 
    (void*)menuDisplayVal, (void*)&value[0] //menuDisplayVal is a function that takes one argument 
}; 

void loop() //Main Loop - just an example of how the function pointed to by curMenuElement is executed 
{ 
    curMenuElement = &menu[0]; 
    if(KP_OK) 
    { 
    (*reinterpret_cast<void (*)(...)>(curMenuElement->OK_func))(curMenuElement->OK_args); //General template for function pointed to at OK_func with OK_args 
    } 
} 

到目前爲止運作良好的一個說法,但我無法弄清楚如何通過在結構體變量的初始化多個參數列表。這甚至可以不必使用使用va_list的構建器函數?

+1

這裏沒有C。只是C++ ...和[void main()'](http://c-faq.com/ansi/voidmain.html)是什麼?和[爲什麼不應用它](http:/ /c-faq.com/ansi/voidmain3.html)? – Sebivor 2013-04-23 22:46:17

+1

將函數指針轉換爲void *'是非法的。 – 2013-04-23 22:50:01

+0

@JesseGood確實。在哪一天和哪個年齡,lambda的類型是「void *」?那將是一個非常混亂的時代! – Sebivor 2013-04-23 22:54:29

回答

0

變量函數只接受棧上的參數。循環必須知道給定函數的結構體中有多少個參數值,然後下拉到彙編程序層以手動將值推入堆棧,然後調用當前函數,然後最終將值從函數退出後堆棧。這當然是可行的,但手動完成很多工作,並且安全地減少了編譯時間。

你最好將結構本身或至少它的成員傳遞給每個函數,讓他們決定如何根據需要使用這些值。例如:

typedef void (*menuFunc)(void** args, int numArgs); 

typedef struct MENUELEMENT 
{ 
    menuFunc OK_func; 
    int OK_num_args; 
    void** OK_args; 
} menuElement_t; 

void menuDisplayText(void** args, int numArgs) 
{ 
    ... 
} 

void menuDisplayVal(void** args, int numArgs) 
{ 
    ... 
} 

void* menuDisplayTextArgs[] = 
{ 
    "Test" 
    &lcdBuffer[0] 
}; 

menuElement_t menu[] = 
{ 
    {&menuDisplayText, 2, menuDisplayTextArgs}, 
    {&menuDisplayVal, 1, &value[0]} 
}; 

void loop() 
{ 
    menuElement_t* curMenuElement = &menu[0]; 
    if (KP_OK) 
    { 
     curMenuElement->OK_func(curMenuElement->OK_args, curMenuElement->OK_num_args); 
    } 
} 
+0

「這當然是可行的」,它只適用於特定的體系結構和調用約定。它將不可移植 – newacct 2013-04-24 00:14:07

+0

當下拉到彙編層時,您必須編寫特定於平臺的指令。在32位平臺上,唯一支持可變參數參數的調用約定是'cdecl',這是一個帶有明確定義的堆棧佈局的可移植調用約定。在64位平臺上,只有一種可用的調用約定,但是AMD與Intel,GCC和VC++等實現可變參數的方式有所不同。所以是的,編寫低級代碼不是很便攜的... – 2013-04-24 01:00:20

+0

.. 。但是,如果你想動態建立一個函數的參數列表,就沒有別的辦法了,就像OP所要求的那樣。強化我的建議甚至不要嘗試它,而是將代碼重新編寫爲更好的語言支持,而不訴諸低級別的詭計,並讓編譯器處理平臺問題。 – 2013-04-24 01:01:25