最近公司需要c++中嵌入lua,抽空学习了下
学习文档:http://www.jb51.net/article/55843.htm
lua语言是嵌入式语言,c/c++和lua是可以相互交互的
第一种情况:c/c++语言具有控制权,Lua是一个库,这种形式的c/c++代码称为应用程序代码
第二种情况:lua具有控制权,c语言是一个库,这个时候c代码就是库代码
应用程序代码和库代码都使用同样的API来与Lua通信,这些API被称为CAPI
对几个头文件进行解释:
lua.h定义了Lua提供的基础函数,包括创建Lua环境,调用Lua函数,读写Lua环境中的全局变量以及注册lua调用的新函数等等
lauxlib.h定义辅助库提供的辅助函数,他的所有定义都以luaL_开头,辅助库是一个使用lua.h中API编写出的一个较高抽象层,lua的所有标准库编写都用到了辅助库,辅助库主要用来解决实际问题,辅助库并没有直接访问Lua的内部,他都是使用官方的基础API来完成所有工作的
头文件lualib.h定义了打开标准库的函数,lua库中没有定义任何全局变量,他的所有状态都保存在动态结构lua_State中,所有的CAPI都要求传入一个指向该结构的指针luaL_newstate:用于创建一个新环境或状态,当lua_newstate创建一个新的环境时,新的环境中并没有包含预定义的函数(eg.print)
为了使lua保持灵活,小巧,所有标准库都被组织到不同的包中,当我们需要使用哪个标准库时,既可以使用lualib.h中定义的函数来打开对应的标准库,而辅助函数luaL_openlibs则可以打开所有的标准库
栈:
lua和c/c++语言通信的主要方法是一个虚拟栈,几乎所有API调用都会操作这个栈上的值,所有的数据交换,无论是lua到c/c++或是c/c++到lua都通过这个栈来完成,栈可以解决lua和c/c++语言之间存在的两大差异:
第一种:lua使用垃圾收集, 而c/c++要求显示的释放内存
第二种:lua使用动态类型,而c语言使用静态类型
为了屏蔽两者之间的差异,让彼此之间交互变得通常,便出现了虚拟栈, 栈中的每个元素都能保存任何类型的lua值
当c/c++代码需要获取lua中的一个值时,只需要调用lua API函数,lua就会将指定的值压入栈中
当c/c++代码将值传递给lua中, 需要先将这个值压入栈, 然后调用lua API,lua就会获得该值并将其从栈中弹出
为了将c/c++类型值压入栈中,或者从栈中获取不同类型的值,就需要为每种类型定义一个特定的函数
lua严格按照LIFO(先进后出)规范来操作这个栈, 但调用lua时,lua只会改变栈的顶部
c/c++代码有更大的自由度, 他可以检索栈中间的元素,甚至在栈中的任意位置插入或删除元素
压入栈
对于每种可以呈现在lua中的c类型,API都有一个对应的压入函数:
void lua_pushnil(lua_State* L);
void lua_pushboolean(lua_State *L, int bool);
void lua_push_number(lua_State *L, lua_Number n);
void lua_pushinteger(lua_State *L, lua_Integer n);
const char* lua_pushlstring(lua_State *L, const char *s, size_t l);
const char* lua_pushstring(lua_State *L, const char *s);
等等....
由于这个栈并不是无限大,当向栈中压入一个元素时,应该确保栈中具有足够的空间, 当lua启动时,lua调用c语言时,栈中至少有20个空闲的槽,这些空间一般情况下是足够的,但是会有特殊情况,如果调用一个具有很多参数的函数,就需要调用lua_checkstack来检查栈中会否有足够的空间