3

同じシグネチャの C 関数が多数あり、それらを Lua に登録したいとします。たとえば、各関数は次のようになります。

void foo(int n)
{
   // do some work
}

それぞれを次のように登録できます。

int wrap_foo(Lua_State *l)
{
   int x = lua_tonumber(l, 1);
   foo(x);
   return 0;
}

lua_pushcfunction(l, wrap_foo);
lua_setglobal(l, "foo");

問題は、コードの繰り返しを避けるために次の関数を実装する方法です。

void register(Lua_State *l, const char *name, void (*f)(int));

おそらく、プリプロセッサ マクロを使用して実行できます (コンパイル時のみ)。もっとエレガントな方法はありますか?外部バインディング ライブラリを使用しないソリューションを希望します。

4

1 に答える 1

2

これはキーワードであるため、名前を付けることはできませんがregister、たとえば と呼ぶと、register_wrapperJames McLaughlin の提案を次のように実装できます。

// wrapper for a C function taking a single number argument
// the C function is bound to this wrapper as an upvalue
int wrapper(lua_State *L)
{
    int x = lua_tonumber(L,1);
    void (*wrapped)(int) = (void (*)(int)) lua_touserdata(L, lua_upvalueindex(1));
    wrapped(x);
    return 0;
}

// bind a C function to our wrapper function
void register_wrapper(lua_State* L, const char* name, void(*wrapped)(int))
{
    lua_pushlightuserdata(L, wrapped);
    lua_pushcclosure(L, wrapper, 1);
    lua_setglobal(L, name);
}

int main()
{
    lua_State *L = luaL_newstate();
    register_wrapper(L, "foo", foo);
    register_wrapper(L, "bar", bar);
    ...
于 2012-07-26T18:50:41.577 に答える