2012-02-22 115 views
5

有一個功能:有沒有辦法來包裝函數有va_args參數?

void some_function(int id,...); 

問題:有沒有辦法來包裝這個功能嗎?這意味着得到的東西是這樣的:

void wrapped_some_function(int id,...) 
{ 
    //do smth 
    some_function(id,...); 
} 
+0

http://stackoverflow.com/questions/9329440/process-va-args-in-c的[轉發在C可變參數函數的調用( – BoBTFish 2012-02-22 11:30:56

+0

可能重複http://stackoverflow.com/questions/150543/forward-an-invocation-of-a-variadic-function-in-c) – sth 2012-02-22 11:58:56

+0

@sth有點區別:我需要包裝一個函數,所以我不能修改源函數。我的答案 – 2r2w 2012-02-22 13:42:43

回答

5

使用gcc,__builtin_apply_args__builtin_apply,記錄here,可以做到。
對於標準C,沒有辦法(其他答案建議可以工作,但它不是100%你要求的)。
但是,如果some_function的變化得到va_list(如vprintfprintf的變體),則可以使用它。

+0

太棒了。你可以指出一些MS視覺工作室的替代品嗎? – 2r2w 2012-02-22 13:37:44

+0

我不知道MS是否有其他選擇。 – ugoren 2012-02-22 13:47:53

1

如果你的編譯器支持variadic macros,也許你可以使用?

#define wrapped_some_function(id, ...) \ 
    do {         \ 
     /* Do something here... */  \ 
     some_function(id, __VA_ARGS__); \ 
    } while (0) 
+0

謝謝。但我需要一個功能 – 2r2w 2012-02-22 13:31:52

0

我假設你包裝的功能並不「知道」的在編譯時傳遞的參數(和它們的類型)的實際數量,否則,你可能只是找回它們並調用包裝的函數。

然後,這隻能通過使用內聯彙編器(因此 - 平臺相關的解決方案)來解決。這也取決於你想如何包裝你的功能,你是否需要爲你的包裝保留堆棧(即你不需要本地函數變量)等。

0

在一般情況下,沒有辦法做到這一點,並且因爲some_function的創建者不應該提供類似的函數vsome_function而不是...,而是一個va_list。具有可變參數列表的函數必須具有其計數器部分,其功能爲va_list。考慮函數對(printf,vprintf),(sprintf,vsprintf),(CString :: Format,CString :: FormatV)。

4

因爲這也被標記爲C++:C++ 11 ftw。

#include <utility> // forward 

template<class... Args> 
void wrapped_some_function(int id, Args&&... args) 
{ 
    //do smth 
    some_function(id, std::forward<Args>(args)...); 
} 
+0

謝謝。有趣。但不是我需要的。我需要C函數 – 2r2w 2012-02-22 13:32:57

+0

@ 2r4w:對不起,但不要標記它C++。 – Xeo 2012-02-22 13:49:00

+0

我刪除了錯誤的標籤。但你的回答很有用 – 2r2w 2012-02-22 13:51:41

相關問題