第一章中,我在VS中,实现了lua与C/C++的交互,了解了它们之间是通过一个虚拟的stack来进行交互的。现在我要继续往下进行,这次的目标很简单:我写一个lua脚本配置文件,然后在VS中通过调用C API,读取配置文件内容。这其实就是第一章说过的lua跟C交互的第一种形式,此时,C拥有控制权,lua只是作为一个库,我们通过C来访问lua。具体代码如下:
#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;
}
default:
{
printf("%s",lua_typename(L ,i));
break;
}
}
printf(" ");
}
printf("\n");
}
void load(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 fiel:%s: ",lua_tostring(L,-1));
stackDump(L);
lua_getglobal(L, "width");
stackDump(L);
lua_getglobal(L, "height");
stackDump(L);
if (!lua_isnumber(L,-1))
printf("height' should be a number\n:");
if(!lua_isnumber(L, 2))
printf("width's should be a number\n");
*w = lua_tointeger(L, -1);
*h = lua_tointeger(L, -2);
}
int _tmain(int argc, _TCHAR* argv[])
{
lua_State *L;
L = luaL_newstate();
int i = 0;
int j = 0;
load(L, "configTest.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
100
the size of stack is:2
100 200
the value of i,j is 200,100
其中configTest.lua 中内容很简单,如下:
width = 100
height = 200
这里解释一下几个C API。lua_loadfile::load a file as a Lua compiled chunk,,but doesn't run it。 Lua handles a chunck as the body of an anonymous function with a variable number of arguments。意思是将文件作为一个编译块进行加载,但不运行。lua中将一个块看做一个匿名函数,这样后面才可以用lua_pcall. 如果单独调用这个接口,我在stack里面打印,发现里面只有有一个boolean值; lua_pcall 以安全模式运行编译好的程序块。 其实也可以用luaL_dofile来代替 luaL_loadfile(L, fname) || lua_pcall(L,0,0,0),意思一样。lua_getgloable 将全局变量压入stack中。在上面的lua_pcall后,stack里面已经没有任何元素,因为它返回结果为0。