2011-05-19 120 views
4

我在一個小問題在這裏運行的簽名,我有了這個函數指針:
修改函數指針

typedef void* (* funcPointer)(const void *in, int ilen, void *out, int *olen) 

而這個功能

void* foo1(const void *in, int ilen, void *out, int *olen) 
{ 
    if(CONST_VALUE_1 > iLen) 
     //do something 
    else 
     //do something else 
    return whatever; 
} 

某處在代碼

// ... 
funcPointer fpointer = foo1; 
if(someArgument > SOME_OTHER_CONSTANT) 
    // where foo2 is the same as foo1 except that it uses CONST_VALUE_2 
    fpointer = foo2; 
bar(someVariable, anotherVariable, fpointer); 
// ... 

正如你所看到的,這個函數的主體中有一個CONST_VALUE_X。我希望能夠刪除常量並改用第五個參數。既然不能修改簽名,我在想,如果有事情做或複製粘貼帶有可能的常量的功能...

謝謝

+0

您是否可以控制傳入回調函數的任何值? – TurqMage 2011-05-19 17:39:56

+0

你能包住它嗎?爲什麼不創建一個採用第5個參數的基本函數,然後從尊重簽名的函數中調用它傳遞CONST_VALUE_X? – slezica 2011-05-19 17:41:12

+0

@TurqMage不,我沒有任何控制桿功能 – ALOToverflow 2011-05-19 17:43:53

回答

1

如果您不能修改函數簽名,就像你說的那樣,你將不會有第五個參數!

我看到三個選項:

  1. 我想你可以鞋拔子成的其他void *一個參數(如定義包含in原始值的結構,而「不變」的值,然後通過這個作爲in)。

  2. 在調用函數之前設置一個全局變量。 這是一個壞主意。

  3. 你可以把這個函數寫成一個宏來避免複製粘貼維護的噩夢。 這是一個壞主意。

+0

是的,這就是我想的,但我希望有一個更好,更清潔的解決方案。 – ALOToverflow 2011-05-19 17:42:51

+2

@Francis:我不確定你期待什麼樣的解決方案!最好和最乾淨的解決方案是修改簽名。如果你不能做到這一點,你會留下如上所述的凌亂的解決方案。 – 2011-05-19 17:44:54

+0

選項#1是最好的選擇。 C語言沒有你想要的高級功能,所以你必須自己創造它。無論如何,讓你做你想做的事情的語言可能會在#1「引擎蓋下」,而且它比預處理器宏或全局變量要乾淨得多。 – 2011-05-24 01:05:22

0

你可以用調用者可以臨時改變的東西(比如全局變量)替換常量。

例如:

int oldLenghtLimit = LengthLimit; 
... call the function ... 
LengthLimit = oldLengthLimit; 

而且,在功能:

void* foo1(const void *in, int ilen, void *out, int *olen) 
{ 
    if(LengthLimit > iLen) 
    //do something 
    else 
    //do something else 
    return whatever; 
} 
+0

當然,只有當我們知道調用者遵循該慣例時,它纔有效。 – csl 2011-05-19 18:42:34

+0

不是真的,因爲在調用之後原始的值會恢復,舊的代碼仍然可以工作(假設'LengthLimit'被初始化爲'CONST_VALUE_1')。 – Lindydancer 2011-05-19 19:07:47

+0

我的意思是說,如果你把五個函數指針交給你無法控制的地方,那麼這些指針就必須遵循這個約定,否則它將不起作用。 – csl 2011-05-19 20:47:33

0

你想被稱爲封閉和C不具有封閉的明確支持什麼。您可以通過修改API來實現相同的功能,以攜帶函數指針和參數指針,而不僅僅是函數指針。然後你只需要這個函數的版本:一個使用顯式調用者提供的參數,另一個使用來自進位參數指針的值。