针对每一种能用 C
语言直接表示的 Lua
数据类型, C API
中都有一个对应的压栈函数:
- 常量
nil
使用lua_pushnil
- 布尔值(在
C
语言中是整型)使用lua_pushboolean
- 双精度浮点数使用
lua_pushnumber
- 整型使用
lua_pushinteger
- 任意字符串(一个指向
char
的指针,外加一个长度)使用lua_pushlstring
- 以
\0
终止的字符串使用lua_pushstring
。
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);
提示
由于历史原因, C API
中的术语 "number"
指的是双精度浮点类型。
当然,也有向栈中压入 C
函数和用户数据的函数,见后续笔记。
类型 lua_Number
相当于 Lua
语言中的浮点数类型,默认为 double
,但可以在编译时配置 Lua
,让 lua_Number
为 float
甚至 long double
。类型 lua_Integer
相当于 Lua
语言中的整型,通常被定义为 long long
,即有符号 64
位整型。同样,要把 Lua
语言中的 lua_Integer
配置为使用 int
或 long
也很容易。如果使用 float-int
组合,也就是 32
位浮点型和整型,即我们所说的精简Lua
( Small Lua
),对于资源受限的及其和硬件而言,相当高效。
提示
对于这些配置,详见头文件 luaconf.h
。
Lua
语言中的字符串不是以 \0
结尾的,他们可以包含任意的二进制数据。因此,将字符串压栈的基本函数 lua_pushlstring
需要一个明确的长度作为参数。对于以 \0
结尾的字符串,也可以使用函数 lua_pushstring
,该函数通过 strlen
来计算字符串的长度。 Lua
语言不会保留指向外部字符串(或指向除静态的 C
语言函数外的任何外部对象)的指针。对于不得不保留的字符串, Lua
要么生成一个内部副本,要么复用已有的字符串。因此,一旦上述函数返回,即使立刻释放或修改缓冲区也不会出现问题。
无论何时向栈内压入一个元素,我们都应该确保栈中有足够的空间。当 Lua
启动时,以及 Lua
调用 C
语言时,栈中至少会有 20
个空闲的位置( slot
)(头文件 lua.h
中将这个常量定义为 LUA_MINSTACK
)。对于大多数情况,这个空间完全够用,所以我们一般无需考虑栈空间的问题。不过,有些任务可能会需要更多的栈空间,特别是循环向栈中压入元素时。在这些情况下,就需要调用函数 lua_checkstack
来检查栈中是否有足够的空间:
int lua_checkstack (lua_State *L, int sz);
这里, sz
是我们所需的额外栈位置的数量。如果可能,函数 lua_checkstack
会增加栈的大小,以容纳所需的额外空间;否则,该函数返回零。
辅助库也提供了一个高层函数来检查栈空间:
void luaL_checkstack(lua_State *L, int sz, const char *msg);
该函数类似于函数 lua_checkstack
,但是如果栈空间不能满足请求,该函数会使用指定的错误信息抛出异常,而不是返回错误码。