lua注册表和引用系统,LUA_REGISTRYINDEX、luaL_ref、luaL_unref的用途

先看两段代码

1: Foo.lua

function foo()
    print("hello world")
end

2:luaRef.cpp


#include <stdlib.h>
#include <lua.hpp>
#include <lualib.h>
#include <lauxlib.h>


int main()
{
    lua_State *L = luaL_newstate();  
    luaL_openlibs(L);
    luaL_dofile(L,"Foo.lua");
    lua_getglobal(L,"foo");
    printf("stack size:%d,%d\n",lua_gettop(L),lua_type(L,-1));
    // 存放函数到注册表中并返回引用
    int ref =  luaL_ref(L,LUA_REGISTRYINDEX);
    printf("stack size:%d\n",lua_gettop(L));

   // 从注册表中读取该函数并调用
    lua_rawgeti(L,LUA_REGISTRYINDEX,ref);
    printf("stack size:%d,%d\n",lua_gettop(L),lua_type(L,-1));
   
    //printf("stack size:%d,%d\n",lua_gettop(L),lua_type(L,-1));
    lua_pcall(L,0,0,0);
    printf("stack size:%d\n",lua_gettop(L));
    printf("------------------------华丽的分割线------------\n");

    lua_getglobal(L,"foo");
    printf("stack size:%d\n",lua_gettop(L));
    lua_setfield(L,LUA_REGISTRYINDEX,"sb");
    printf("stack size:%d\n",lua_gettop(L));
    lua_getfield(L,LUA_REGISTRYINDEX,"sb");
    lua_pcall(L,0,0,0);
    printf("------------------------又一次华丽的分割线------------\n");
    printf("stack size:%d,%d\n",lua_gettop(L),lua_type(L,-1));
    luaL_unref(L,LUA_REGISTRYINDEX,ref);
    lua_rawgeti(L,LUA_REGISTRYINDEX,ref);
    printf("stack size:%d\n",lua_gettop(L));
    lua_getfield(L,LUA_REGISTRYINDEX,"sb");
    lua_pcall(L,0,0,0);
    lua_close(L);

   return 0;
}

3:编译运行整个程序


[root@localhost testLua]# g++ -g luaRef.cpp -ldl -llua 
[root@localhost testLua]# ./a.out 
stack size:1,6
stack size:0
stack size:1,6
hello world
stack size:0
------------------------华丽的分割线------------
stack size:1
stack size:0
hello world
------------------------又一次华丽的分割线------------
stack size:0,0
stack size:1
hello world

4.1:从程序的运行结果可以知道:luaL_ref返回一个int的值ref。ref这个值就是对应的value(foo函数)的key,通过API方法    lua_rawgeti(L,LUA_REGISTRYINDEX,ref);可以从注册表获取到对应的value(foo函数)。一旦ref在注册表的引用解除,就无法继续通过ref这个引用获取到value(即foo函数)。


4.2:如果想在c模块之间通过ref来引用到value(即foo函数)。也是可以的。但是c模块之间必须共享ref的值。这里就不写测试用例了。


4.3:注册表的key也可以C/C++静态变量地址作为key;C连接器可以确保这个key在整个注册表中的唯一性。

static int i =0;

lua_pushlightuserdata(L, (void*) &i) ;  /**取静态变量i的地址作为key压栈**/

lua_pushInteger(L, "value");   /**把值压栈**/

lua_settable(L, LUA_REGISTERINDEX); /** &i, value出栈;并且实现register[&i] = value**/


lua_pushlightuserdata(L, (void*) &i) ;  /**取静态变量i的地址作为key压栈**/

lua_gettable(L, LUA_REGISTERINDEX); /**获取value值,如果函数调用成功,那么value目前在栈顶**/

const char* str = lua_tostring(L,-1);



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值