在 Lua 中注册具有相同签名的 C 函数。

假设我们有多个具有相同签名的 C 函数,我们想要将它们注册到 Lua。例如,每个函数看起来像这样:

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

我们可以使用以下代码将它们注册到 Lua:

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));

可能可以使用预处理器宏(仅在编译时)来完成。是否有更优雅的方法?我希望能够找到一种不使用任何外部绑定库的解决方案。

点赞
用户501459
用户501459

你不能将其命名为 register,因为那是一个关键字,但如果我们将它称为 register_wrapper,我们可以像这样实现 James McLaughlin 的建议:

// 一个包装 C 函数的函数,该 C 函数需要一个数字参数
// C 函数绑定到这个包装程序作为一个 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;
}

// 将一个 C 函数绑定到我们的包装程序函数
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-26 18:50:41