zoukankan      html  css  js  c++  java
  • C中调用LUA回调(LUA注册表)

    实现原理:

    通过将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
    ");
    
        /** 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
    ");
    
            /** 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;
    }
     
     

    Published with Luweimy
  • 相关阅读:
    最全的项目
    最全的liunx系统修改root用户密码
    最全docker安装步骤
    最全的ideal 常 用 的 快 捷
    最全的ideal 常用的快捷
    ftp路径
    站点路径
    sublime text3 切换中文方法
    UI设计: PS 快捷键 Ctrl+Shift+alt+T,旋转复制
    SQL中表与表的简单关系
  • 原文地址:https://www.cnblogs.com/luweimy/p/3972353.html
Copyright © 2011-2022 走看看