2011-02-28 48 views
5

我從這個中文博客中得到這個問題http://chenyufei.info/blog/2011-02-28/wrap-c-function-closure-gcc-nested-function/ 作者想用c語言實現閉包,他發現GCC有嵌套函數(和閉包)的能力。 例如:關於換行和調用C函數

typedef int (*func_t)(int arg); 


int foo(int a) { 

    return a + 1; 

} 


func_t create_wrap_function(func_t f) { 

    int wrapped(int arg) { 

     // call original function 

     int val = f(arg); 

     fprintf(log_func_call, "arg: %d ret: %d", arg, val); 

     return val; 
    } 

    return wrapped; 
} 

但它不是常見的解決方案。 create_wrap_function具有固定的函數格式,因爲func_t限制了格式。

我們知道,Lua已經關閉了,並且也可以調用C函數。 我想要實現的內容如下: 我們想要調用的函數是foo1和foo2,它們具有不同類型的參數和返回值。

int foo1(int a) { 
    ... 
    return intValue; 
} 

double foo2(char* str, double a) { 
    ... 
    return dblValue; 
} 

在C端,呼叫等功能:

lua_returnValue returnValue1 = Do_Lua_Wrap(__FILE__, __LINE__, foo1, 1); 
lua_returnValue returnValue2 = Do_Lua_Wrap(__FILE__, __LINE__, foo2, "string data", 1.2345); 

在Do_Lua_Wrap,它將foo1和1傳遞到Lua函數,然後調用函數foo1像正常過程。 然後將foo2和一個char *以及一個double值傳遞給Lua函數,然後像正常進程那樣調用foo2函數。 在Lua函數中,它可以記錄有關FILELINE 的信息並寫入一些關於函數參數的額外日誌。

但我不知道如何編寫函數Do_Lua_Wrap在C和Lua中, 是否有可能?

如果可能,你能給我一些建議嗎?

回答

2

你明顯對variadic function感興趣,但麻煩在於確定推入到Lua棧中的參數類型。我給你推薦幾個方法:

  1. 首先將包括 格式字符串一拉常常在較高的水平 語言中使用的printf 家庭或二進制格式打包 。例如,使用 lpack Lua模塊中使用的格式,查看 。關鍵是通過 掃描格式字符串到 確定提供了多少個參數和什麼樣的 參數。

  2. 或者,您可以實施 variant類型。每個參數 將需要包裝在這樣的 結構中。另外,需要提供 參數的總數作爲第一個參數 。

  3. 最後,您可以將參數傳遞給兩個 數組,而不是使用可變參數 函數。第一個陣列 包含對應於第二個陣列中void *指針的目標的枚舉類型 。這種方法需要最多的房屋 保持客戶端代碼,但是 相當乾淨。指定數組長度的參數或一個或兩個數組末尾的標記值也是必需的。

希望這些方法中的一種應該適合您。就我個人而言,我會選擇第一個選項,並使用lpack代碼作爲指導。它最接近您的問題中指定的功能簽名。

+0

你的回答非常棒! – sagasw