• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C中调用LUA回调(LUA注册表)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

实现原理:

通过将LUA中得回调函数存入LUA注册表中来保存LUA函数,然后在需要回调时从LUA注册表中取出LUA函数进行调用

下面是一些预备知识:(学习两个重要的函数)

原汁原味的英文解释的最透彻,翻译的话就会加入自己的理解


LUA_GLOBALSINDEX
LUA_ENVIRONINDEX
LUA_REGISTRYINDEX
Lua provides a registry, a pre-defined table that can be used by any C code to store whatever Lua value it needs to store. This table is always located at pseudo-index LUA_REGISTRYINDEX. Any C library can store data into this table, but it should take care to choose keys different from those used by other libraries, to avoid collisions. Typically, you should use as key a string containing your library name or a light userdata with the address of a C object in your code
 
int luaL_ref (lua_State *L, int t);

Creates and returns a reference, in the table at index t, for the object at the top of the stack (and pops the object).

A reference is a unique integer key. As long as you do not manually add integer keys into table tluaL_ref ensures the uniqueness of the key it returns. You can retrieve an object referred by reference r by calling lua_rawgeti(L, t, r). Function luaL_unref frees a reference and its associated object.

If the object at the top of the stack is nilluaL_ref returns the constant LUA_REFNIL. The constant LUA_NOREF is guaranteed to be different from any reference returned by luaL_ref.


 

void luaL_unref (lua_State *L, int t, int ref);

Releases reference ref from the table at index t (see luaL_ref). The entry is removed from the table, so that the referred object can be collected. The reference ref is also freed to be used again.

If ref is LUA_NOREF or LUA_REFNILluaL_unref does nothing.

这样使用

将lua函数保存到这个注册表。lua提供了在表里增加一个条目的API,luaL_ref,返回值是新条目的key,一个整数。
int handler = luaL_ref( L , LUA_REGISTRYINDEX );
下面是简化后的代码,是保存lua中传入的一个function,并将其作为回掉函数调用
代码如下:
 int Test_callback(lua_State* luaState)
{
    int topindex = lua_gettop(luaState);
    assert(topindex == 1);
    /** check stack top is lua function */
    if (!lua_isfunction(luaState, topindex))
      generate_error(luaState, "param #1 is not function\n");

    /** register lua function to register table and we can use with func id
        luaL_ref will pops the stack top */
    int luafuncid = luaL_ref(luaState, LUA_REGISTRYINDEX);

    { /** Wait a moment */
        /** get function by ref id */
        lua_rawgeti(luaState, LUA_REGISTRYINDEX, luafuncid);
        if (!lua_isfunction(luaState, -1))
            generate_error(luaState, "callback is not a lua function\n");

        /** push params */ 
        
        /** call lua function */
        if (lua_pcall(luaState, 0, 0, 0) != 0) {
            /** error message on the stack top, lua_error will jump */
            lua_error(luaState);
        }
        luaL_unref(luaState, LUA_REGISTRYINDEX, luafuncid);
    }
    return 0;

}

 
extern int luaopen_Test_luabinding(lua_State* luaState)
{
    static const struct luaL_Reg funcs[] = {
        {"callback", Test_callback},
        {NULL, NULL}
    };
    luaL_register(luaState, "test", funcs);
    return 1;
}

 

 
 

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
(转)luadump函数发布时间:2022-07-22
下一篇:
lua环境揭秘发布时间:2022-07-22
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap