2011-02-28 9 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です。それらは異なるタイプのargsと戻り値を持っています。 Cクライアントで

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

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

、のような関数を呼び出す:

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

、それは通常のプロセスのようfoo1の関数を呼び出し、次に、Luaの関数にfoo1の1を通過します。 次に、foo2と1つのchar *と1つのdouble値をLua関数に渡し、foo2関数を通常のプロセスのように呼び出します。 Lua関数では、FILELINE の情報をログに記録し、関数の引数についての余分なログを書き込むことができます。

しかし、私はDo_Lua_Wrap関数をCとLuaに書く方法について考えていません。 可能でしょうか?

可能であれば、アドバイスをいただけますか?

答えて

2

明らかに、variadic functionに興味がありますが、問題はLuaスタックにプッシュする引数のタイプを決定することです。私は、カップルのアプローチをお勧めします:

  1. は、最初は フォーマット文字列ラしばしば、より高いレベル 言語で使用printf 家族やバイナリ梱包形式 を含めることであろう。たとえば、 を、 lpack Luaモジュールで使用されているフォーマットパターンで見てください。キーは にフォーマット文字列をスキャンして に何個と何種類の 引数が指定されているかを判断することです。

  2. また、 variantタイプを実装することもできます。各引数 は、 構造体にラップする必要があります。また、 引数の合計数は、最初のパラメータとして を指定する必要があります。

  3. 最後に、バリアブル 関数を使用する代わりに、2つの 配列で引数を渡すことができます。最初の配列 は、void *のターゲットに対応する列挙型 を2番目の配列に含みます。この方法では、クライアントコードを維持するのに最も多くの家屋が必要ですが、 はきれいです。配列の長さを指定する引数、または一方または両方の配列の末尾に西暦 の値が必要です。

うまくいけば、これらの方法のうちの1つがうまくいくはずです。個人的には、最初のオプションを使用してlpackコードをガイドとして使用します。これはあなたの質問にも指定された関数の署名に最も近いものです。

+0

あなたは答えが素晴らしいです! – sagasw

関連する問題