首先咱们来说一下栈:
api
lua与c语言通信的主要方法是经过一个无所不在的虚拟栈。几乎全部的api调用都会操做这个栈上的值:全部的数据交换,不管是lua到c语言或c语言到lua都是经过这个栈来完成。栈能够解决lua与c语言之间存在的两大差别,第一个差别时lua使用垃圾回收收集,而c语言要求显示地释放内存;第二种是lua使用动态类型,而c语言使用静态类型。
函数
咱们来看一下c与lua之间是怎么通信的:(假如c语言想知道lua中的money字符串的值)
lua
1.c想获取lua中的money字符串的值,须要c把money房放到栈顶,以便lua能看到。
spa
2.lua从栈顶中获取money,此时栈顶再次变为空
指针
3.lua经过money这个字段在其全局表中进行查找
code
4.全局表返回money对应的值,假设为10000
索引
5.lua把取得的10000放到栈顶
内存
6.c能够从栈顶取得10000
rem
咱们来看一下栈的操做:
字符串
1.压入栈:
对于每种能够呈如今lua中的c类型,api都有一个对应的压入函数,以下:
void lua_pushnil(lua_State *L); void lua_pushboolean(lua_State *L, int bool); void lua_pushnumber(lua_State *L, lua_Number n); void lua_pushinteger(lua_State *L, lua_Integer n); void lua_pushlstring(lua_State *L, const char *s, size_t len); void lua_pushstring(lua_State *L, const char *s);
2.查询元素:
api使用索引来访问栈中的元素。第一个压入栈中的元素索引为1,第二个压入的元素索引为2,以此类推,直到栈顶。我么也能够用栈顶做为参考物,使用负数来访问栈中的元素。此时-1表示栈顶元素,-2表示栈顶下面的元素,以此类推。
为了检查一个元素是否为特定的类型,api提供了一系列的函数lua_is*,其中*能够是任意lua类型。这些函数有lua_number、lua_isstring和lua_istable等,原型以下:
int lua_is*(lua_State *L, int index);
3.取值:
咱们通常使用lua_to*函数从栈中获取一个值,以下:
lua_Number lua_tonumber (lua_State *L, int idx); lua_Integer lua_tointeger (lua_State *L, int idx); int lua_toboolean (lua_State *L, int idx); const char *lua_tolstring (lua_State *L, int idx, size_t *len); size_t lua_objlen (lua_State *L, int idx); lua_CFunction lua_tocfunction (lua_State *L, int idx); void *lua_touserdata (lua_State *L, int idx); lua_State *lua_tothread (lua_State *L, int idx); const void *lua_topointer (lua_State *L, int idx);
若是指定的元素不具备正确的类型,调用这些函数也不会有问题。在这种状况下,lua_toboolean、lua_tonumber、lua_tointeger和lua_objlen会返回0,而其它函数会返回NULL。lua_tolstring函数会返回一个指向内部字符串副本的指针,并将字符串的长度存入最后一个参数len中。这个内部副本不能修改,返回类型中的const也说明了这点。Lua保证只要这个对应的字符串还在栈中,那么这个指针就是有效的。当Lua调用的一个C函数返回时,Lua就会清空它的栈。
栈的其它操做:
--返回栈中元素的个数,也能够说是栈顶元素的索引 int lua_gettop (lua_State *L); --将栈顶设置为一个指定的位置,即修改栈中元素的数量,若是以前的栈顶比新设置的更高,那么高出来的这些元素会被丢弃--;反之,会向栈中压入nil来补足大小.lua_settop(L, 0);表示清空栈 void lua_settop (lua_State *L, int idx); --将指定索引上值得副本压入栈 void lua_pushvalue (lua_State *L, int idx); --删除指定索引上的元素,并将该位置之上的全部元素下移以填补空缺 void lua_remove (lua_State *L, int idx); --上移指定位置之上的全部元素以开辟一个槽空间,而后将栈顶元素移到该位置 void lua_insert (lua_State *L, int idx); --弹出栈顶的值,并将该值设置到指定索引上,但它不会移动任何东西,只是替换了指定索引的值 void lua_replace (lua_State *L, int idx);