无论你何时想要从Lua 请求一个值(比如一个全局变量的值),调用Lua,被请求的值将会被压入栈。无论你何时想要传递一个值给Lua,首先将这个值压入栈,然后调用Lua(这个值将被弹出)。
Lua 以一个严格的LIFO 规则(后进先出;也就是说,始终存取栈顶)来操作栈。当你调用Lua 时,它只会改变栈顶部分。你的C代码却有更多的自由;更明确的来讲,你可以查询栈上的任何元素,甚至是在任何一个位置插入和删除元素。
一、压入元素:
void lua_pushnil (lua_State *L);
void lua_pushboolean (lua_State *L, int bool);
void lua_pushnumber (lua_State *L, double n);
void lua_pushlstring (lua_State *L, const char *s,
size_t length);
void lua_pushstring (lua_State *L, const char *s);
当Lua 在起始以及在Lua 调用C 的时候,栈上至少有20 个空闲的记录(lua.h 中的LUA_MINSTACK 宏定义了这个常量)。对于多数普通的用法栈是足够的,所以通常我们不必去考虑它。这个函数检测栈上是否有足够你需要的空间:
int lua_checkstack (lua_State *L, int sz);
二、查询元素
API 用索引来访问栈中的元素。在栈中的第一个元素(也就是第一个被压入栈的)有索引1,下一个有索引2,以此类推。我们也可以用栈顶作为参照来存取元素,利用负索引。在这种情况下,-1 指出栈顶元素(也就是最后被压入的),-2 指出它的前一个元素,以此类推。
1.类型判断
API 提供了一套lua_is*函数来检查一个元素是否是一个指定的类型,*可以是任何Lua 类型。因此有lua_isnumber,lua_isstring,lua_istable 以及类似的函数。所有这些函数都有同样的原型:
int lua_is... (lua_State *L, int index);
2.返回元素类型
还有一个 lua_type 函数,它返回栈中元素的类型。(lua_is*中的有些函数实际上是用了这个函数定义的宏)在lua.h 头文件中,每种类型都被定义为一个常量:LUA_TNIL、LUA_TBOOLEAN 、LUA_TNUMBER 、LUA_TSTRING 、LUA_TTABLE 、LUA_TFUNCTION、LUA_TUSERDATA 以及LUA_TTHREAD。这个函数主要被用在与一个switch 语句联合使用。当我们需要真正的检查字符串和数字类型时它也是有用的。
3.从栈中获得值
从栈中获得值,这里有 lua_to*函数:
int lua_toboolean (lua_State *L, int index);
double lua_tonumber (lua_State *L, int index);
const char * lua_tostring (lua_State *L, int index);
size_t lua_strlen (lua_State *L, int index);
因为非数字返回0,5.2可以通过如下函数的isnum参数接收是否是一个数字:
lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum);
lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum);
lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum);
Lua_string 返回的字符串结尾总会有一个字符结束标志0,但是字符串中间也可能包含0,lua_strlen 返回字符串的实际长度。
const char *s = lua_tostring(L, -1); /* any Lua string */
size_t l = lua_strlen(L, -1); /* its length */
assert(s[l] == '\0');
assert(strlen(s) <= l);
三、栈中其它操作
int lua_gettop (lua_State *L);
void lua_settop (lua_State *L, int index);
void lua_pushvalue (lua_State *L, int index);
void lua_remove (lua_State *L, int index);
void lua_insert (lua_State *L, int index);
void lua_replace (lua_State *L, int index);
void lua_copy (lua_State *L, int fromidx, int toidx);
函数lua_gettop 返回堆栈中的元素个数,它也是栈顶元素的索引。
lua_settop 设置栈顶(也就是堆栈中的元素个数)为一个指定的值。如果开始的栈顶高于新的栈顶,顶部的值被丢弃。否则,为了得到指定的大小这个函数压入相应个数的空值(nil)到栈上。
函数lua_pushvalue 压入堆栈上指定索引的一个拷贝到栈顶;
lua_remove 移除指定索引位置的元素,并将其上面所有的元素下移来填补这个位置的空白;
lua_insert 移动栈顶元素到指定索引的位置,并将这个索引位置上面的元素全部上移至栈顶被移动留下的空
隔;
lua_replace 从栈顶弹出元素值并将其设置到指定索引位置,没有任何移动操作。