lua 中 lua_gettable的使用 C++ 调用lua 读取table

  尝试着从C中读取lua中的table。 lua中提供lua_gettable 的C接口。例如我们要从a.lua中读取一个全局变量 background

--=================
-- file name :a.lua
--================

background = {r=0,g=0,b=255}

先写一个读取table值的接口

void getRGBValue(lua_State *L,const char *fname,int *r,int *g,int *b)
{
	//加载lua文件,并执行
	if (luaL_loadfile(L,fname) || lua_pcall(L,0,0,0) )
	{
		luaL_error(L,"cannot run config.file: %s",lua_tostring(L,-1));
		return;

	}
	//读取background table,并将background对象压栈
	lua_getglobal(L,"background");
	//判断是否是table类型
	if (!lua_istable(L,-1))
	{
		luaL_error(L,"'background is not a table'");
		return;
	}

	//获取颜色值
	*r =  getField(L,"r") ;
	*g =  getField(L,"g") ;
	*b =  getField(L,"b");
}

这边主要做的事情是读取lua文件,获取background对象,并压栈,然后调用getField接口取出table中各元素的值,getField是自己实现的接口,并非lua提供的C API

下面是getField的实现

int getField(lua_State *L,const char* name)
{
	//  将key 压栈,
	lua_pushstring(L,name);
	//gettable接口会根据栈顶的key索引,取出key对应的值,
	//将值压栈,这个时候栈顶的key被value覆盖,上面压了key进来,所以table目前的位置是-2的位置
	lua_gettable(L,-2);

	//类型检查
	if (!lua_isnumber(L,-1))
	{
		luaL_error(L,"attempt to call a not number value");
		return 0;
	}

	//转换成整形
	int result = lua_tonumber(L,-1);

	//将栈顶的元素出栈,还原成调用前的栈,以便下一次调用
	lua_pop(L,1);
	
	return result;
}


执行getField前,栈里只有table,如图

lua 中 lua_gettable的使用 C++ 调用lua 读取table_第1张图片

执行getField 首先第一步 执行lua_pushstring(L,name); 将key值入栈,这个时候栈顶的元素就是key

lua 中 lua_gettable的使用 C++ 调用lua 读取table_第2张图片

接下来执行 lua_gettable(L,-2),因为栈顶是key,所以table的位置是在倒数第二的位置,也就是-2的位置,执行gettable,这个接口会根据栈顶的key值取出key对应的background中的值,也就是background[key] 的值,放入栈顶,覆盖原来的key

lua 中 lua_gettable的使用 C++ 调用lua 读取table_第3张图片
将这个转换成我们想要的类型,然后执行lua_pop(L,1); 谈出栈的一个元素,也就是栈顶,value出栈,这个时候栈就变成了原来的样子以确保下次调用的时候table原始样

lua 中 lua_gettable的使用 C++ 调用lua 读取table_第4张图片

以上就是我对lua_gettable 的理解,是否是这样,其实可以通过lua_gettop 获取栈的元素,然后遍历这些元素,获取他们的类型去验证一下

具体的验证方法大概是这样的

int nNum = lua_gettop(L);
for (int i = 1; i <= nTop; ++i){
    int nType = lua_type(L,i);
    switch(nType) {
    //这里省略了具体的类型  
    ....
    }
}
以上是个人的学习小计,如果有错误的地方,烦请指出,相互学习,互免!

你可能感兴趣的:(lua)