Lua与C/C++的交互3:C/C++中读取Lua文件中的表

在第二章中,我在vs中通过用c/c++调用跟lua交互的C API,成功读取了lua配置文件中的内容:一个全局变量。这次,我要稍微深入一点:在lua文件中定义一个表,然后用C/C++读取表中的内容。这个其实跟第二章原理是一样的,只是,这里有个细节,这个细节就是lua_getfield. 以下是完整源代码:

#include "stdafx.h"
#include "stdio.h"
extern "C"
{
	#include "lua.h"
	#include "lualib.h"
	#include "lauxlib.h"
};

#pragma comment(lib,"lua5.1.lib")

void stackDump(lua_State *L)
{
	int i;
	int top = lua_gettop(L);
	printf("the size of stack is:%d\n",top);
	for ( i = 1;i <= top;i++ )
	{
		int type = lua_type(L, i);
		switch(type)
		{
		case LUA_TSTRING:
			{
				printf("%s",lua_tostring(L, i));
				break;
			}

		case LUA_TBOOLEAN:
			{
				printf(lua_toboolean(L, i)?"true":"false");
				break;
			}
		case LUA_TNUMBER:
			{
				printf("%g",lua_tonumber(L, i));
				break;
			}
		case LUA_TTABLE:
			{
				printf("this is a table!");
				break;
			}
		default:
			{
				printf("%s",lua_typename(L ,i));
				break;
			}
		}
		printf(" ");
	}
	printf("\n");
}

//获取lua文件中类型为表的变量
void loadConfigTable(lua_State *L,const char *fname, int *w, int *h)
{
	if ( luaL_loadfile(L, fname) || lua_pcall(L,0,0,0) )
		printf("error,can't run config file:%s:",lua_tostring(L,-1));
	stackDump(L);
	lua_getglobal(L, "color");	//获取lua文件中的表color,压入栈顶
	if ( !lua_istable(L, -1) ) 
		printf("error,color is not a table");
	stackDump(L);
	lua_getfield(L, -1, "red");	//获取color表中key为red的value。获取前color表位于栈顶
	if ( !lua_isnumber(L,-1) )
		printf("error,color type is not a number");
	stackDump(L);
	*w = lua_tointeger(L, -1);
	lua_pop(L, 1);				//从栈中弹出一个元素,即弹出栈顶值
	lua_getfield(L, -1, "white");
	if ( !lua_isnumber(L, -1) )
		printf("error,color type is not a number");
	stackDump(L);
	*h = lua_tointeger(L, -1);
}

int _tmain(int argc, _TCHAR* argv[])
{
	lua_State *L;
	L = luaL_newstate();
	luaL_openlibs(L);	
	int i = 0;
	int j = 0;
	loadConfigTable(L, "configTable.lua", &i, &j);
	printf("the value of i,j is %d,%d",i,j);
	return 0;
}
打印信息如下:

the size of stack is:0

the size of stack is:1
this is a table!
the size of stack is:2
this is a table! 1
the size of stack is:2
this is a table! 4
the value of i,j is 1,4

其中configTable.lua文件内容如下:

color = {red = 1,green = 2,yellow = 3,white = 4,brown = 5}

详细讲解下lua_getfield(lua_State *L, int idx, const char *k),这个函数用以获取表中对应key的value。其中参数idx是表在栈中的位置,k是表中的key。其实它就相当于这两个函数的组合,lua_pushstring(L, key) && lua_gettable(L, idx),这里key必须位于栈顶。所以要想获取栈中表对于key的value,我们需要把key压入栈顶,然后通过lua_gettable(L, idx)弹出栈顶key,同时将key对应的value压入栈顶。
在上面的程序中,先用lua_getglobal(l, "color")获取lua中的表color后压入栈顶,现在栈顶的值是一个表。接着调用lua_getfield(L, -1, "red"),此时表位于栈顶,所以idx为-1,调用过程是,red先被压入栈顶,然后从栈顶弹出,栈顶元素被red对应的value,即1取代。现在栈顶值为1,栈底值为table,接着lua_pop后,继续获取表中其他key对应的value。

你可能感兴趣的:(lua)