Lua中的CAPI概述
头文件
lua.h: Lua提供的基础函数,包括创建Lua环境,调用Lua函数,读写Lua环境中的全局变量,以及注册供Lua调用的新函数等。lua.h中的函数都有lua_前缀
lauxlib.h: 辅助库(auxiliary lib).所有定义以luaL_开头
lualib.h: lua库函数,大部分以luaopen_开头,用于开启某个lua的库。以及luaL_openlibs函数,开启全部标准库。
环境:
eclipse(C++) + LDT(site:http://download.eclipse.org/ldt/releases/stable)
system: mac
一个简单Lua解释器程序
//main.c
int error; lua_State* L = luaL_newstate(); /*打开Lua*/
luaL_openlibs(L);/*打开标准库*/
const char* lua_code = "print('test lua c')"
error = luaL_loadbuffer(L,lua_code,strlen(lua_code),"line") || lua_pcall(L,0,0,0);
if(error)
{
fprintf(stderr,"%s",lua_tostring(L,-1));/*获得消息并打印*/
lua_pop(L,1); /*从栈中弹出错误消息*/
}
lua_close(L);
Lua没有全局变量,所有状态保存在lua_State中。
luaL_newstate:创建一个新的lua_State,此时连print都没有,需要调用luaL_openlibs添加全部标准库
luaL_loadbuffer:编译每行的内容。没有错误,返回0,并向栈中压入编译后的程序块。
lua_pcall 将程序块从栈中弹出,并在保护模式中运行,没有错误返回0.有错误,返回错误码并压入一条错误消息到栈中。
Lua的栈
Lua使用一个抽象的栈,在Lua和C语言之间交换数据。(LIFO 后进先出),Lua只会改变栈的顶部。
默认栈至少20个空闲的槽(LUA_MINSTACK),可以使用int lua_checkstack(lua_StateL,int sz);来检查
压入元素:lua_push[nil,boolean,number,integer,lstring,string]
查询:lua_is[nil,boolean,..] (luaStateL, int index) 第一个压入栈的元素为1,第二个压入栈的元素为2,此外,-1表示栈顶元素(最后压入的元素),-2表示其下面的元素
lua_tostring: 返回的字符串尾部有额外的'\0'
lua_objlen: 获得对象的长度,这个值是长度操作符'#'的结果。
lua_error: 当C函数监测到一个错误时,它就应该调用lua_error。lua_error会清理Lua中所有需要清理的东西,然后跳回发起执行的那个lua_pcall,并附上一条错误消息。
/*打印luaState的栈信息*/
static void stackDump(lua_State* L){
int i;
int top = lua_gettop(L);
for(i=1;i<=top;i++){
int t = lua_type(L,i);
switch(t){
case LUA_TSTRING:{
printf("'%s'",lua_tostring(L,i));
break;
}
clase LUA_TBOOLEAN:{
printf(lua_toboolean(L,i)?"true":"false");
break;
}
case LUA_TNUMBER:{
printf("%g",lua_tonumber(L,i))
}
default:{
printf("%s",lua_typename(L,t))
}
print(" ");
}
}
}
其它栈操作
int lua_getttop(lua_State*L) //栈顶的索引(-1等价于这个数)
void lua_settop(lua_State*,int index) //将栈顶设置为一个指定位置,如果高,这填充nil,否则丢弃
void lua_pushvalue(lua_State*,int index) //将指定索引上值得副本压入栈
void lua_remove(lua_State*,int index) //删除指定位置上的元素
void lua_insert(lua_State*,int index) //上移位置之上元素,开辟一个新的空间,将栈顶元素移到该位置
void lua_replace(lua_State*,int index) //弹出栈顶的值,然后将此值设置到指定索引上,不会移动任何值
//从栈中弹出n个元素
#define lua_pop(L,n) lua_settop(L,-(n)-1)
//stackDump
static void stackDump(){...}
int main(void){
lua_State*L = luaL_newstate();
lua_pushboolean(L,1);
lua_pushnumber(L,10);
lua_pushnil(L);
lua_pushstring(L,"hello");
stackDump(L);// (底-4)true,10,nil,'hello'
lua_pushvalue(L,-4);
stackDump(L);//(1,-5)true,10,nil,'hello',true(5,-1)
lua_replace(L,3);
stackDump(L);// true,10,true,'hello'
lua_settop(L,6);
stackDump(L);//true,10,true,'hello'(-3),nil,nil(-1)
lua_remove(L,-3); //true,10,true,nil,nil
lua_settop(L,-5); //true
lua_close(L);
}