4.8 函数和类型

这里按字母次序列出了所有 C API 中的函数和类型。每个函数都有一个这样的提示:[-o, +p, x]

对于第一个域,o,指的是该函数会从栈上弹出多少个元素。第二个域,p,指该函数会将多少个元素压栈。(所有函数都会在弹出参数后再把结果压栈。)x|y 这种形式的域表示该函数根据具体情况可能压入(或弹出)xy 个元素;问号 '?' 表示我们无法仅通过参数来了解该函数会弹出/压入多少元素(比如,数量取决于栈上有些什么)。第三个域,x,解释了该函数是否会抛出错误:'-' 表示该函数绝对不会抛出错误;'e' 表示该函数可能抛出错误;'v' 表示该函数可能抛出有意义的错误。


lua_absindex

[-0, +0, –]

  1. int lua_absindex (lua_State *L, int idx);

将一个可接受的索引 idx 转换为绝对索引(即,一个不依赖栈顶在哪的值)。


lua_Alloc

  1. typedef void * (*lua_Alloc) (void *ud,
  2. void *ptr,
  3. size_t osize,
  4. size_t nsize);

Lua 状态机中使用的内存分配器函数的类型。内存分配函数必须提供一个功能类似于 realloc但又不完全相同的函数。它的参数有ud ,一个由lua_newstate 传给它的指针;ptr ,一个指向已分配出来/将被重新分配/要释放的内存块指针;osize ,内存块原来的尺寸或是关于什么将被分配出来的代码;nsize ,新内存块的尺寸。

如果 ptr 不是 NULLosizeptr 指向的内存块的尺寸,即这个内存块当初被分配或重分配的尺寸。

如果 ptrNULLosize 是 Lua 即将分配对象类型的编码。当(且仅当)Lua 创建一个对应类型的新对象时,osizeLUA_TSTRINGLUA_TTABLELUA_TFUNCTIONLUA_TUSERDATA,或 LUA_TTHREAD 中的一个。若 osize 是其它类型,Lua 将为其它东西分配内存。

Lua 假定分配器函数会遵循以下行为:

nsize 是零时,分配器必须和 free 行为类似并返回 NULL

nsize 不是零时,分配器必须和realloc 行为类似。如果分配器无法完成请求,返回 NULL。Lua 假定在 osize >= nsize 成立的条件下,分配器绝不会失败。

这里有一个简单的分配器函数的实现。这个实现被放在补充库中,供luaL_newstate 使用。

  1. static void *l_alloc (void *ud, void *ptr, size_t osize,
  2. size_t nsize) {
  3. (void)ud; (void)osize; /* not used */
  4. if (nsize == 0) {
  5. free(ptr);
  6. return NULL;
  7. }
  8. else
  9. return realloc(ptr, nsize);
  10. }

注意,标准 C 能确保 free(NULL) 没有副作用,且 realloc(NULL,size) 等价于 malloc(size)。这段代码假定 realloc 在缩小块长度时不会失败。(虽然标准 C 没有对此行为做出保证,但这看起来是一个安全的假定。)


lua_arith

[-(2|1), +1, e]

  1. void lua_arith (lua_State *L, int op);

对栈顶的两个值(或者一个,比如取反)做一次数学或位操作。其中,栈顶的那个值是第二个操作数。它会弹出压入的值,并把结果放在栈顶。这个函数遵循 Lua 对应的操作符运算规则(即有可能触发元方法)。

op 的值必须是下列常量中的一个:

  • LUA_OPADD: 加法 (+)
  • LUA_OPSUB: 减法 (-)
  • LUA_OPMUL: 乘法 (*)
  • LUA_OPDIV: 浮点除法 (/)
  • LUA_OPIDIV: 向下取整的除法 (//)
  • LUA_OPMOD: 取模 (%)
  • LUA_OPPOW: 乘方 (^)
  • LUA_OPUNM: 取负 (一元 -)
  • LUA_OPBNOT: 按位取反 (~)
  • LUA_OPBAND: 按位与 (&)
  • LUA_OPBOR: 按位或 (|)
  • LUA_OPBXOR: 按位异或 (~)
  • LUA_OPSHL: 左移 (<<)
  • LUA_OPSHR: 右移 (>>)

lua_atpanic

[-0, +0, –]

  1. lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);

设置一个新的 panic 函数,并返回之前设置的那个。(参见 §4.6)。


lua_call

[-(nargs+1), +nresults, e]

  1. void lua_call (lua_State *L, int nargs, int nresults);

调用一个函数。

要调用一个函数请遵循以下协议:首先,要调用的函数应该被压入栈;接着,把需要传递给这个函数的参数按正序压栈;这是指第一个参数首先压栈。最后调用一下 lua_callnargs 是你压入栈的参数个数。当函数调用完毕后,所有的参数以及函数本身都会出栈。而函数的返回值这时则被压栈。返回值的个数将被调整为 nresults 个,除非 nresults 被设置成 LUA_MULTRET。在这种情况下,所有的返回值都被压入堆栈中。 Lua 会保证返回值都放入栈空间中。函数返回值将按正序压栈(第一个返回值首先压栈),因此在调用结束后,最后一个返回值将被放在栈顶。

被调用函数内发生的错误将(通过 longjmp )一直上抛。

下面的例子中,这行 Lua 代码等价于在宿主程序中用 C 代码做一些工作:

  1. a = f("how", t.x, 14)

这里是 C 里的代码:

  1. lua_getglobal(L, "f"); /* function to be called */
  2. lua_pushliteral(L, "how"); /* 1st argument */
  3. lua_getglobal(L, "t"); /* table to be indexed */
  4. lua_getfield(L, -1, "x"); /* push result of t.x (2nd arg) */
  5. lua_remove(L, -2); /* remove 't' from the stack */
  6. lua_pushinteger(L, 14); /* 3rd argument */
  7. lua_call(L, 3, 1); /* call 'f' with 3 arguments and 1 result */
  8. lua_setglobal(L, "a"); /* set global 'a' */

注意上面这段代码是 平衡 的:到了最后,堆栈恢复成原有的配置。这是一种良好的编程习惯。


lua_callk

[-(nargs + 1), +nresults, e]

  1. void lua_callk (lua_State *L,
  2. int nargs,
  3. int nresults,
  4. lua_KContext ctx,
  5. lua_KFunction k);

这个函数的行为和 lua_call完全一致,只不过它还允许被调用的函数让出(参见 §4.7)。


lua_CFunction

  1. typedef int (*lua_CFunction) (lua_State *L);

C 函数的类型。

为了正确的和 Lua 通讯,C 函数必须使用下列协议。这个协议定义了参数以及返回值传递方法:C 函数通过 Lua 中的栈来接受参数,参数以正序入栈(第一个参数首先入栈)。因此,当函数开始的时候,lua_gettop(L) 可以返回函数收到的参数个数。第一个参数(如果有的话)在索引 1 的地方,而最后一个参数在索引 lua_gettop(L) 处。 当需要向 Lua 返回值的时候,C 函数只需要把它们以正序压到堆栈上(第一个返回值最先压入),然后返回这些返回值的个数。在这些返回值之下的,堆栈上的东西都会被 Lua 丢掉。和 Lua 函数一样,从 Lua 中调用 C 函数也可以有很多返回值。

下面这个例子中的函数将接收若干数字参数,并返回它们的平均数与和:

  1. static int foo (lua_State *L) {
  2. int n = lua_gettop(L); /* 参数的个数 */
  3. lua_Number sum = 0.0;
  4. int i;
  5. for (i = 1; i <= n; i++) {
  6. if (!lua_isnumber(L, i)) {
  7. lua_pushliteral(L, "incorrect argument");
  8. lua_error(L);
  9. }
  10. sum += lua_tonumber(L, i);
  11. }
  12. lua_pushnumber(L, sum/n); /* 第一个返回值 */
  13. lua_pushnumber(L, sum); /* 第二个返回值 */
  14. return 2; /* 返回值的个数 */
  15. }

lua_checkstack

[-0, +0, –]

  1. int lua_checkstack (lua_State *L, int n);

确保堆栈上至少有 n 个额外空位。如果不能把堆栈扩展到相应的尺寸,函数返回假。失败的原因包括将把栈扩展到比固定最大尺寸还大(至少是几千个元素)或分配内存失败。这个函数永远不会缩小堆栈;如果堆栈已经比需要的大了,那么就保持原样。


lua_close

[-0, +0, –]

  1. void lua_close (lua_State *L);

销毁指定 Lua 状态机中的所有对象(如果有垃圾收集相关的元方法的话,会调用它们),并且释放状态机中使用的所有动态内存。在一些平台上,你可以不必调用这个函数, 因为当宿主程序结束的时候,所有的资源就自然被释放掉了。另一方面,长期运行的程序,比如一个后台程序或是一个网站服务器,会创建出多个 Lua 状态机。那么就应该在不需要时赶紧关闭它们。


lua_compare

[-0, +0, e]

  1. int lua_compare (lua_State *L, int index1, int index2, int op);

比较两个 Lua 值。当索引 index1 处的值通过 op和索引 index2 处的值做比较后条件满足,函数返回 1 。这个函数遵循 Lua 对应的操作规则(即有可能触发元方法)。反之,函数返回 0。当任何一个索引无效时,函数也会返回 0 。

op 值必须是下列常量中的一个:

  • LUA_OPEQ: 相等比较 (==)
  • LUA_OPLT: 小于比较 (<)
  • LUA_OPLE: 小于等于比较 (<=)

lua_concat

[-n, +1, e]

  1. void lua_concat (lua_State *L, int n);

连接栈顶的 n 个值,然后将这些值出栈,并把结果放在栈顶。如果 n 为 1 ,结果就是那个值放在栈上(即,函数什么都不做);如果 n 为 0 ,结果是一个空串。 连接依照 Lua 中通常语义完成(参见 §3.4.6 )。


lua_copy

[-0, +0, –]

  1. void lua_copy (lua_State *L, int fromidx, int toidx);

从索引 fromidx 处复制一个值到一个有效索引toidx 处,覆盖那里的原有值。不会影响其它位置的值。


lua_createtable

[-0, +1, e]

  1. void lua_createtable (lua_State *L, int narr, int nrec);

创建一张新的空表压栈。参数 narr 建议了这张表作为序列使用时会有多少个元素;参数 nrec 建议了这张表可能拥有多少序列之外的元素。Lua 会使用这些建议来预分配这张新表。如果你知道这张表用途的更多信息,预分配可以提高性能。否则,你可以使用函数 lua_newtable


lua_dump

[-0, +0, e]

  1. int lua_dump (lua_State *L,
  2. lua_Writer writer,
  3. void *data,
  4. int strip);

把函数导出成二进制代码块 。函数接收栈顶的 Lua 函数做参数,然后生成它的二进制代码块。若被导出的东西被再次加载,加载的结果就相当于原来的函数。当它在产生代码块的时候,lua_dump通过调用函数 writer(参见 lua_Writer )来写入数据,后面的 data 参数会被传入 writer

如果 strip 为真,二进制代码块将不包含该函数的调试信息。

最后一次由 writer 的返回值将作为这个函数的返回值返回;0 表示没有错误。

该函数不会把 Lua 函数弹出堆栈。


lua_error

[-1, +0, v]

  1. int lua_error (lua_State *L);

以栈顶的值作为错误对象,抛出一个 Lua 错误。这个函数将做一次长跳转,所以一定不会返回(参见 luaL_error)。


lua_gc

[-0, +0, e]

  1. int lua_gc (lua_State *L, int what, int data);

控制垃圾收集器。

这个函数根据其参数 what 发起几种不同的任务:

  • LUA_GCSTOP: 停止垃圾收集器。

  • LUA_GCRESTART: 重启垃圾收集器。

  • LUA_GCCOLLECT: 发起一次完整的垃圾收集循环。

  • LUA_GCCOUNT: 返回 Lua 使用的内存总量(以 K 字节为单位)。

  • LUA_GCCOUNTB: 返回当前内存使用量除以 1024 的余数。

  • LUA_GCSTEP: 发起一步增量垃圾收集。

  • LUA_GCSETPAUSE: data 设为 垃圾收集器间歇率 (参见 §2.5),并返回之前设置的值。

  • LUA_GCSETSTEPMUL: data 设为 垃圾收集器步进倍率 (参见 §2.5),并返回之前设置的值。

  • LUA_GCISRUNNING: 返回收集器是否在运行(即没有停止)。

关于这些选项的细节,参见 collectgarbage


lua_getallocf

[-0, +0, –]

  1. lua_Alloc lua_getallocf (lua_State *L, void **ud);

返回给定状态机的内存分配器函数。如果 ud 不是 NULL ,Lua 把设置内存分配函数时设置的那个指针置入 *ud


lua_getfield

[-0, +1, e]

  1. int lua_getfield (lua_State *L, int index, const char *k);

t[k] 的值压栈,这里的 t 是索引指向的值。在 Lua 中,这个函数可能触发对应 "index" 事件对应的元方法(参见 §2.4 )。

函数将返回压入值的类型。


lua_getextraspace

[-0, +0, –]

  1. void *lua_getextraspace (lua_State *L);

返回一个 Lua 状态机中关联的内存块指针。程序可以把这块内存用于任何用途;而 Lua 不会使用它。

每一个新线程都会携带一块内存,初始化为主线程的这块内存的副本。

默认配置下,这块内存的大小为空指针的大小。不过你可以重新编译 Lua 设定这块内存不同的大小。(参见 luaconf.h 中的 LUA_EXTRASPACE。)


lua_getglobal

[-0, +1, e]

  1. int lua_getglobal (lua_State *L, const char *name);

把全局变量 name 里的值压栈,返回该值的类型。


lua_geti

[-0, +1, e]

  1. int lua_geti (lua_State *L, int index, lua_Integer i);

t[i] 的值压栈,这里的 t 指给定的索引指代的值。和在 Lua 里一样,这个函数可能会触发 "index" 事件的元方法(参见 §2.4)。

返回压入值的类型。


lua_getmetatable

[-0, +(0|1), –]

  1. int lua_getmetatable (lua_State *L, int index);

如果该索引处的值有元表,则将其元表压栈,返回 1 。否则不会将任何东西入栈,返回 0 。


lua_gettable

[-1, +1, e]

  1. int lua_gettable (lua_State *L, int index);

t[k] 的值压栈,这里的 t 是指索引指向的值,而 k 则是栈顶放的值。

这个函数会弹出堆栈上的键,把结果放在栈上相同位置。和在 Lua 中一样,这个函数可能触发对应 "index" 事件的元方法 (参见 §2.4 )。

返回压入值的类型。


lua_gettop

[-0, +0, –]

  1. int lua_gettop (lua_State *L);

返回栈顶元素的索引。 因为索引是从 1 开始编号的,所以这个结果等于栈上的元素个数;特别指出,0 表示栈为空。


lua_getuservalue

[-0, +1, –]

  1. int lua_getuservalue (lua_State *L, int index);

将给定索引处的用户数据所关联的 Lua 值压栈。

返回压入值的类型。


lua_insert

[-1, +1, –]

  1. void lua_insert (lua_State *L, int index);

把栈顶元素移动到指定的有效索引处,依次移动这个索引之上的元素。不要用伪索引来调用这个函数,因为伪索引没有真正指向栈上的位置。


lua_Integer

  1. typedef ... lua_Integer;

Lua 中的整数类型。

缺省时,这个就是 long long,(通常是一个 64 位以二为补码的整数),也可以修改它为 longint(通常是一个 32 位以二为补码的整数)。(参见 luaconf.h 中的 LUA_INT 。)

Lua 定义了两个常量:LUA_MININTEGERLUA_MAXINTEGER来表示这个类型可以表示的最小和最大值。


lua_isboolean

[-0, +0, –]

  1. int lua_isboolean (lua_State *L, int index);

当给定索引的值是一个布尔量时,返回 1 ,否则返回 0 。


lua_iscfunction

[-0, +0, –]

  1. int lua_iscfunction (lua_State *L, int index);

当给定索引的值是一个 C 函数时,返回 1 ,否则返回 0 。


lua_isfunction

[-0, +0, –]

  1. int lua_isfunction (lua_State *L, int index);

当给定索引的值是一个函数( C 或 Lua 函数均可)时,返回 1 ,否则返回 0 。


lua_isinteger

[-0, +0, –]

  1. int lua_isinteger (lua_State *L, int index);

当给定索引的值是一个整数(其值是一个数字,且内部以整数储存),时,返回 1 ,否则返回 0 。


lua_islightuserdata

[-0, +0, –]

  1. int lua_islightuserdata (lua_State *L, int index);

当给定索引的值是一个轻量用户数据时,返回 1 ,否则返回 0 。


lua_isnil

[-0, +0, –]

  1. int lua_isnil (lua_State *L, int index);

当给定索引的值是 nil 时,返回 1 ,否则返回 0 。


lua_isnone

[-0, +0, –]

  1. int lua_isnone (lua_State *L, int index);

当给定索引无效时,返回 1 ,否则返回 0 。


lua_isnoneornil

[-0, +0, –]

  1. int lua_isnoneornil (lua_State *L, int index);

当给定索引无效或其值是 nil 时,返回 1 ,否则返回 0 。


lua_isnumber

[-0, +0, –]

  1. int lua_isnumber (lua_State *L, int index);

当给定索引的值是一个数字,或是一个可转换为数字的字符串时,返回 1 ,否则返回 0 。


lua_isstring

[-0, +0, –]

  1. int lua_isstring (lua_State *L, int index);

当给定索引的值是一个字符串或是一个数字(数字总能转换成字符串)时,返回 1 ,否则返回 0 。


lua_istable

[-0, +0, –]

  1. int lua_istable (lua_State *L, int index);

当给定索引的值是一张表时,返回 1 ,否则返回 0 。


lua_isthread

[-0, +0, –]

  1. int lua_isthread (lua_State *L, int index);

当给定索引的值是一条线程时,返回 1 ,否则返回 0 。


lua_isuserdata

[-0, +0, –]

  1. int lua_isuserdata (lua_State *L, int index);

当给定索引的值是一个用户数据(无论是完全的还是轻量的)时,返回 1 ,否则返回 0 。


lua_isyieldable

[-0, +0, –]

  1. int lua_isyieldable (lua_State *L);

如果给定的协程可以让出,返回 1 ,否则返回 0 。


lua_KContext

  1. typedef ... lua_KContext;

延续函数上下文参数的类型。这一定是一个数字类型。当有 intptr_t 时,被定义为 intptr_t ,因此它也可以保存指针。否则,它被定义为 ptrdiff_t


lua_KFunction

  1. typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);

延续函数的类型(参见 §4.7 )。


lua_len

[-0, +1, e]

  1. void lua_len (lua_State *L, int index);

返回给定索引的值的长度。它等价于 Lua 中的 '#' 操作符(参见 §3.4.7)。它有可能触发 "length" 事件对应的元方法(参见 §2.4 )。结果压栈。


lua_load

[-0, +1, –]

  1. int lua_load (lua_State *L,
  2. lua_Reader reader,
  3. void *data,
  4. const char *chunkname,
  5. const char *mode);

加载一段 Lua 代码块,但不运行它。如果没有错误,lua_load 把一个编译好的代码块作为一个 Lua 函数压到栈顶。否则,压入错误消息。

lua_load 的返回值可以是:

  • LUA_OK: 没有错误;

  • LUA_ERRSYNTAX: 在预编译时碰到语法错误;

  • LUA_ERRMEM: 内存分配错误;

  • LUA_ERRGCMM: 在运行 __gc 元方法时出错了。(这个错误和代码块加载过程无关,它是由垃圾收集器引发的。)

lua_load 函数使用一个用户提供的 reader函数来读取代码块(参见 lua_Reader )。data 参数会被传入 reader 函数。

chunkname 这个参数可以赋予代码块一个名字,这个名字被用于出错信息和调试信息(参见 §4.9)。

lua_load 会自动检测代码块是文本的还是二进制的,然后做对应的加载操作(参见程序 luac )。字符串 mode 的作用和函数 load一致。它还可以是 NULL 等价于字符串 "bt"。

lua_load 的内部会使用栈,因此 reader 函数必须永远在每次返回时保留栈的原样。

如果返回的函数有上值,第一个上值会被设置为保存在注册表(参见 §4.5LUA_RIDX_GLOBALS 索引处的全局环境。在加载主代码块时,这个上值是 _ENV 变量(参见 §2.2)。其它上值均被初始化为 nil


lua_newstate

[-0, +0, –]

  1. lua_State *lua_newstate (lua_Alloc f, void *ud);

创建一个运行在新的独立的状态机中的线程。如果无法创建线程或状态机(由于内存有限)则返回 NULL。参数 f 是一个分配器函数; Lua 将通过这个函数做状态机内所有的内存分配操作。第二个参数 ud ,这个指针将在每次调用分配器时被转入。


lua_newtable

[-0, +1, e]

  1. void lua_newtable (lua_State *L);

创建一张空表,并将其压栈。它等价于 lua_createtable(L, 0, 0)


lua_newthread

[-0, +1, e]

  1. lua_State *lua_newthread (lua_State *L);

创建一条新线程,并将其压栈,并返回维护这个线程的 lua_State 指针。这个函数返回的新线程共享原线程的全局环境, 但是它有独立的运行栈。

没有显式的函数可以用来关闭或销毁掉一个线程。线程跟其它 Lua 对象一样是垃圾收集的条目之一。


lua_newuserdata

[-0, +1, e]

  1. void *lua_newuserdata (lua_State *L, size_t size);

这个函数分配一块指定大小的内存块,把内存块地址作为一个完全用户数据压栈,并返回这个地址。宿主程序可以随意使用这块内存。


lua_next

[-1, +(2|0), e]

  1. int lua_next (lua_State *L, int index);

从栈顶弹出一个键,然后把索引指定的表中的一个键值对压栈 (弹出的键之后的 “下一” 对)。如果表中以无更多元素,那么 lua_next 将返回 0 (什么也不压栈)。

典型的遍历方法是这样的:

  1. /* 表放在索引 't' 处 */
  2. lua_pushnil(L); /* 第一个键 */
  3. while (lua_next(L, t) != 0) {
  4. /* 使用 '键' (在索引 -2 处) 和 '值' (在索引 -1 处)*/
  5. printf("%s - %s\n",
  6. lua_typename(L, lua_type(L, -2)),
  7. lua_typename(L, lua_type(L, -1)));
  8. /* 移除 '值' ;保留 '键' 做下一次迭代 */
  9. lua_pop(L, 1);
  10. }

在遍历一张表的时候,不要直接对键调用lua_tolstring ,除非你知道这个键一定是一个字符串。调用 lua_tolstring 有可能改变给定索引位置的值;这会对下一次调用 lua_next 造成影响。

关于迭代过程中修改被迭代的表的注意事项参见next 函数。


lua_Number

  1. typedef double lua_Number;

Lua 中浮点数的类型。

Lua 中数字的类型。缺省是 double ,但是你可以改成 float 。(参见 luaconf.h 中的 LUA_REAL 。)


lua_numbertointeger

  1. int lua_numbertointeger (lua_Number n, lua_Integer *p);

将一个 Lua 浮点数转换为一个 Lua 整数。这个宏假设 n 有对应的整数值。如果该值在 Lua 整数可表示范围内,就将其转换为一个整数赋给 *p。宏的结果是一个布尔量,表示转换是否成功。(注意、由于圆整关系,这个范围测试不用此宏很难做对。)

该宏有可能对其参数做多次取值。


lua_pcall

[-(nargs + 1), +(nresults|1), –]

  1. int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);

以保护模式调用一个函数。

nargsnresults 的含义与 lua_call 中的相同。如果在调用过程中没有发生错误,lua_pcall 的行为和 lua_call 完全一致。 但是,如果有错误发生的话,lua_pcall 会捕获它,然后把唯一的值(错误消息)压栈,然后返回错误码。 同 lua_call 一样,lua_pcall 总是把函数本身和它的参数从栈上移除。

如果 msgh 是 0 ,返回在栈顶的错误消息就和原始错误消息完全一致。否则, msgh 就被当成是 错误处理函数 在栈上的索引位置。 (在当前的实现里,这个索引不能是伪索引。)在发生运行时错误时,这个函数会被调用而参数就是错误消息。错误处理函数的返回值将被 lua_pcall作为错误消息返回在堆栈上。

典型的用法中,错误处理函数被用来给错误消息加上更多的调试信息,比如栈跟踪信息。这些信息在 lua_pcall 返回后,由于栈已经展开,所以收集不到了。

lua_pcall 函数会返回下列常数(定义在 lua.h 内)中的一个:

  • LUA_OK (0): 成功。
  • LUA_ERRRUN: 运行时错误。
  • LUA_ERRMEM: 内存分配错误。对于这种错,Lua 不会调用错误处理函数。
  • LUA_ERRERR: 在运行错误处理函数时发生的错误。
  • LUA_ERRGCMM: 在运行 __gc 元方法时发生的错误。(这个错误和被调用的函数无关。)

lua_pcallk

[-(nargs + 1), +(nresults|1), –]

  1. int lua_pcallk (lua_State *L,
  2. int nargs,
  3. int nresults,
  4. int msgh,
  5. lua_KContext ctx,
  6. lua_KFunction k);

这个函数的行为和 lua_pcall完全一致,只不过它还允许被调用的函数让出(参见 §4.7)。


lua_pop

[-n, +0, –]

  1. void lua_pop (lua_State *L, int n);

从栈中弹出 n 个元素。


lua_pushboolean

[-0, +1, –]

  1. void lua_pushboolean (lua_State *L, int b);

b 作为一个布尔量压栈。


lua_pushcclosure

[-n, +1, e]

  1. void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);

把一个新的 C 闭包压栈。

当创建了一个 C 函数后,你可以给它关联一些值,这就是在创建一个 C 闭包(参见 §4.4);接下来无论函数何时被调用,这些值都可以被这个函数访问到。为了将一些值关联到一个 C 函数上,首先这些值需要先被压入堆栈(如果有多个值,第一个先压)。接下来调用 lua_pushcclosure来创建出闭包并把这个 C 函数压到栈上。参数 n 告之函数有多少个值需要关联到函数上。lua_pushcclosure 也会把这些值从栈上弹出。

n 的最大值是 255 。

n 为零时,这个函数将创建出一个 轻量 C 函数,它就是一个指向 C 函数的指针。这种情况下,不可能抛出内存错误。


lua_pushcfunction

[-0, +1, –]

  1. void lua_pushcfunction (lua_State *L, lua_CFunction f);

将一个 C 函数压栈。 这个函数接收一个 C 函数指针,并将一个类型为 function 的 Lua 值压栈。当这个栈顶的值被调用时,将触发对应的 C 函数。

注册到 Lua 中的任何函数都必须遵循正确的协议来接收参数和返回值(参见 lua_CFunction )。

lua_pushcfunction 是作为一个宏定义出现的:

  1. #define lua_pushcfunction(L,f) lua_pushcclosure(L,f,0)

lua_pushfstring

[-0, +1, e]

  1. const char *lua_pushfstring (lua_State *L, const char *fmt, ...);

把一个格式化过的字符串压栈,然后返回这个字符串的指针。 它和 C 函数 sprintf 比较像,不过有一些重要的区别:

  • 你不需要为结果分配空间:其结果是一个 Lua 字符串,由 Lua 来关心其内存分配 (同时通过垃圾收集来释放内存)。
  • 这个转换非常的受限。不支持符号、宽度、精度。转换符只支持'%%' (插入一个字符 '%'),'%s' (插入一个带零终止符的字符串,没有长度限制),'%f' (插入一个 lua_Number),'%I' (插入一个 lua_Integer),'%p' (插入一个指针或是一个十六进制数),'%d' (插入一个 int),'%c' (插入一个用 int 表示的单字节字符),以及'%U' (插入一个用 long int 表示的 UTF-8 字)。

lua_pushglobaltable

[-0, +1, –]

  1. void lua_pushglobaltable (lua_State *L);

将全局环境压栈。


lua_pushinteger

[-0, +1, –]

  1. void lua_pushinteger (lua_State *L, lua_Integer n);

把值为 n 的整数压栈。


lua_pushlightuserdata

[-0, +1, –]

  1. void lua_pushlightuserdata (lua_State *L, void *p);

把一个轻量用户数据压栈。

用户数据是保留在 Lua 中的 C 值。轻量用户数据 表示一个指针 void*。它是一个像数字一样的值:你不需要专门创建它,它也没有独立的元表,而且也不会被收集(因为从来不需要创建)。只要表示的 C 地址相同,两个轻量用户数据就相等。


lua_pushliteral

[-0, +1, e]

  1. const char *lua_pushliteral (lua_State *L, const char *s);

这个宏等价于 lua_pushstring,区别仅在于只能在 s 是一个字面量时才能用它。它会自动给出字符串的长度。


lua_pushlstring

[-0, +1, e]

  1. const char *lua_pushlstring (lua_State *L, const char *s, size_t len);

把指针 s 指向的长度为 len 的字符串压栈。Lua 对这个字符串做一个内部副本(或是复用一个副本),因此 s 处的内存在函数返回后,可以释放掉或是立刻重用于其它用途。字符串内可以是任意二进制数据,包括零字符。

返回内部副本的指针。


lua_pushnil

[-0, +1, –]

  1. void lua_pushnil (lua_State *L);

将空值压栈。


lua_pushnumber

[-0, +1, –]

  1. void lua_pushnumber (lua_State *L, lua_Number n);

把一个值为 n 的浮点数压栈。


lua_pushstring

[-0, +1, e]

  1. const char *lua_pushstring (lua_State *L, const char *s);

将指针 s 指向的零结尾的字符串压栈。Lua 对这个字符串做一个内部副本(或是复用一个副本),因此 s 处的内存在函数返回后,可以释放掉或是立刻重用于其它用途。

返回内部副本的指针。

如果 sNULL,将 nil 压栈并返回 NULL


lua_pushthread

[-0, +1, –]

  1. int lua_pushthread (lua_State *L);

L 表示的线程压栈。如果这个线程是当前状态机的主线程的话,返回 1 。


lua_pushvalue

[-0, +1, –]

  1. void lua_pushvalue (lua_State *L, int index);

把栈上给定索引处的元素作一个副本压栈。


lua_pushvfstring

[-0, +1, e]

  1. const char *lua_pushvfstring (lua_State *L,
  2. const char *fmt,
  3. va_list argp);

等价于 lua_pushfstring ,不过是用 va_list 接收参数,而不是用可变数量的实际参数。


lua_rawequal

[-0, +0, –]

  1. int lua_rawequal (lua_State *L, int index1, int index2);

如果索引 index1 与索引 index2 处的值本身相等(即不调用元方法),返回 1 。否则返回 0 。当任何一个索引无效时,也返回 0 。


lua_rawget

[-1, +1, –]

  1. int lua_rawget (lua_State *L, int index);

类似于 lua_gettable ,但是作一次直接访问(不触发元方法)。


lua_rawgeti

[-0, +1, –]

  1. int lua_rawgeti (lua_State *L, int index, lua_Integer n);

t[n] 的值压栈,这里的 t 是指给定索引处的表。这是一次直接访问;就是说,它不会触发元方法。

返回入栈值的类型。


lua_rawgetp

[-0, +1, –]

  1. int lua_rawgetp (lua_State *L, int index, const void *p);

t[k] 的值压栈,这里的 t 是指给定索引处的表,k 是指针 p 对应的轻量用户数据。这是一次直接访问;就是说,它不会触发元方法。

返回入栈值的类型。


lua_rawlen

[-0, +0, –]

  1. size_t lua_rawlen (lua_State *L, int index);

返回给定索引处值的固有“长度”:对于字符串,它指字符串的长度;对于表;它指不触发元方法的情况下取长度操作('#')应得到的值;对于用户数据,它指为该用户数据分配的内存块的大小;对于其它值,它为 0 。


lua_rawset

[-2, +0, e]

  1. void lua_rawset (lua_State *L, int index);

类似于 lua_settable ,但是是做一次直接赋值(不触发元方法)。


lua_rawseti

[-1, +0, e]

  1. void lua_rawseti (lua_State *L, int index, lua_Integer i);

等价于 t[i] = v ,这里的 t 是指给定索引处的表,而 v 是栈顶的值。

这个函数会将值弹出栈。赋值是直接的;即不会触发元方法。


lua_rawsetp

[-1, +0, e]

  1. void lua_rawsetp (lua_State *L, int index, const void *p);

等价于 t[k] = v ,这里的 t 是指给定索引处的表,k 是指针 p 对应的轻量用户数据。而 v 是栈顶的值。

这个函数会将值弹出栈。赋值是直接的;即不会触发元方法。


lua_Reader

  1. typedef const char * (*lua_Reader) (lua_State *L,
  2. void *data,
  3. size_t *size);

lua_load 用到的读取器函数,每次它需要一块新的代码块的时候,lua_load 就调用读取器,每次都会传入一个参数 data 。读取器需要返回含有新的代码块的一块内存的指针,并把 size 设为这块内存的大小。内存块必须在下一次函数被调用之前一直存在。读取器可以通过返回 NULL 或设 size 为 0 来指示代码块结束。读取器可能返回多个块,每个块可以有任意的大于零的尺寸。


lua_register

[-0, +0, e]

  1. void lua_register (lua_State *L, const char *name, lua_CFunction f);

把 C 函数 f 设到全局变量 name 中。它通过一个宏定义:

  1. #define lua_register(L,n,f) \
  2. (lua_pushcfunction(L, f), lua_setglobal(L, n))

lua_remove

[-1, +0, –]

  1. void lua_remove (lua_State *L, int index);

从给定有效索引处移除一个元素,把这个索引之上的所有元素移下来填补上这个空隙。不能用伪索引来调用这个函数,因为伪索引并不指向真实的栈上的位置。


lua_replace

[-1, +0, –]

  1. void lua_replace (lua_State *L, int index);

把栈顶元素放置到给定位置而不移动其它元素(因此覆盖了那个位置处的值),然后将栈顶元素弹出。


lua_resume

[-?, +?, –]

  1. int lua_resume (lua_State *L, lua_State *from, int nargs);

在给定线程中启动或延续一条协程 。

要启动一个协程的话,你需要把主函数以及它需要的参数压入线程栈;然后调用 lua_resume ,把 nargs 设为参数的个数。这次调用会在协程挂起时或是结束运行后返回。当函数返回时,堆栈中会有传给 lua_yield 的所有值,或是主函数的所有返回值。当协程让出, lua_resume返回 LUA_YIELD,若协程结束运行且没有任何错误时,返回 0 。如果有错则返回错误代码(参见 lua_pcall )。

在发生错误的情况下,堆栈没有展开,因此你可以使用调试 API 来处理它。错误消息放在栈顶在。

要延续一个协程,你需要清除上次 lua_yield 遗留下的所有结果,你把需要传给yield 作结果的值压栈,然后调用lua_resume

参数 from 表示协程从哪个协程中来延续 L 的。如果不存在这样一个协程,这个参数可以是 NULL


lua_rotate

[-0, +0, –]

  1. void lua_rotate (lua_State *L, int idx, int n);

把从 idx 开始到栈顶的元素轮转 n 个位置。对于 n 为正数时,轮转方向是向栈顶的;当 n 为负数时,向栈底方向轮转 -n 个位置。n 的绝对值不可以比参于轮转的切片长度大。


lua_setallocf

[-0, +0, –]

  1. void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);

把指定状态机的分配器函数换成带上用户数据 udf


lua_setfield

[-1, +0, e]

  1. void lua_setfield (lua_State *L, int index, const char *k);

做一个等价于 t[k] = v 的操作,这里 t 是给出的索引处的值,而 v 是栈顶的那个值。

这个函数将把这个值弹出栈。跟在 Lua 中一样,这个函数可能触发一个 "newindex" 事件的元方法(参见 §2.4)。


lua_setglobal

[-1, +0, e]

  1. void lua_setglobal (lua_State *L, const char *name);

从堆栈上弹出一个值,并将其设为全局变量 name 的新值。


lua_seti

[-1, +0, e]

  1. void lua_seti (lua_State *L, int index, lua_Integer n);

做一个等价于 t[n] = v 的操作,这里 t 是给出的索引处的值,而 v 是栈顶的那个值。

这个函数将把这个值弹出栈。跟在 Lua 中一样,这个函数可能触发一个 "newindex" 事件的元方法(参见 §2.4)。


lua_setmetatable

[-1, +0, –]

  1. void lua_setmetatable (lua_State *L, int index);

把一张表弹出栈,并将其设为给定索引处的值的元表。


lua_settable

[-2, +0, e]

  1. void lua_settable (lua_State *L, int index);

做一个等价于 t[k] = v 的操作,这里 t 是给出的索引处的值,v 是栈顶的那个值,k 是栈顶之下的值。

这个函数会将键和值都弹出栈。跟在 Lua 中一样,这个函数可能触发一个 "newindex" 事件的元方法(参见 §2.4)。


lua_settop

[-?, +?, –]

  1. void lua_settop (lua_State *L, int index);

参数允许传入任何索引以及 0 。它将把堆栈的栈顶设为这个索引。如果新的栈顶比原来的大,超出部分的新元素将被填为 nil 。如果 index 为 0 ,把栈上所有元素移除。


lua_setuservalue

[-1, +0, –]

  1. void lua_setuservalue (lua_State *L, int index);

从栈上弹出一个值并将其设为给定索引处用户数据的关联值。


lua_State

  1. typedef struct lua_State lua_State;

一个不透明的结构,它指向一条线程并间接(通过该线程)引用了整个 Lua 解释器的状态。Lua 库是完全可重入的:它没有任何全局变量。状态机所有的信息都可以通过这个结构访问到。

这个结构的指针必须作为第一个参数传递给每一个库函数。lua_newstate 是一个例外,这个函数会从头创建一个 Lua 状态机。


lua_status

[-0, +0, –]

  1. int lua_status (lua_State *L);

返回线程 L 的状态。

正常的线程状态是 0 (LUA_OK)。当线程用 lua_resume 执行完毕并抛出了一个错误时,状态值是错误码。如果线程被挂起,状态为LUA_YIELD

你只能在状态为 LUA_OK 的线程中调用函数。你可以延续一个状态为 LUA_OK的线程(用于开始新协程)或是状态为 LUA_YIELD 的线程(用于延续协程)。


lua_stringtonumber

[-0, +1, –]

  1. size_t lua_stringtonumber (lua_State *L, const char *s);

将一个零结尾的字符串 s 转换为一个数字,将这个数字压栈,并返回字符串的总长度(即长度加一)。转换的结果可能是整数也可能是浮点数,这取决于 Lua 的转换语法(参见 §3.1)。这个字符串可以有前置和后置的空格以及符号。如果字符串并非一个有效的数字,返回 0 并不把任何东西压栈。(注意,这个结果可以当成一个布尔量使用,为真即转换成功。)


lua_toboolean

[-0, +0, –]

  1. int lua_toboolean (lua_State *L, int index);

把给定索引处的 Lua 值转换为一个 C 中的布尔量( 0 或是 1 )。和 Lua 中做的所有测试一样, lua_toboolean 会把任何不同于 falsenil 的值当作真返回;否则就返回假。(如果你想只接收真正的 boolean 值,就需要使用 lua_isboolean 来测试值的类型。)


lua_tocfunction

[-0, +0, –]

  1. lua_CFunction lua_tocfunction (lua_State *L, int index);

把给定索引处的 Lua 值转换为一个 C 函数。这个值必须是一个 C 函数;如果不是就返回 NULL


lua_tointeger

[-0, +0, –]

  1. lua_Integer lua_tointeger (lua_State *L, int index);

等价于调用 lua_tointegerx,其参数 isnumNULL


lua_tointegerx

[-0, +0, –]

  1. lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);

将给定索引处的 Lua 值转换为带符号的整数类型lua_Integer。这个 Lua 值必须是一个整数,或是一个可以被转换为整数(参见 §3.4.3)的数字或字符串;否则,lua_tointegerx 返回 0 。

如果 isnum 不是 NULL*isnum 会被设为操作是否成功。


lua_tolstring

[-0, +0, e]

  1. const char *lua_tolstring (lua_State *L, int index, size_t *len);

把给定索引处的 Lua 值转换为一个 C 字符串。如果len 不为 NULL ,它还把字符串长度设到 *len 中。这个 Lua 值必须是一个字符串或是一个数字; 否则返回返回 NULL 。如果值是一个数字, luatolstring还会 把堆栈中的那个值的实际类型转换为一个字符串_。(当遍历一张表的时候,若把lua_tolstring 作用在键上,这个转换有可能导致 lua_next 弄错。)

lua_tolstring 返回一个已对齐指针指向 Lua 状态机中的字符串。这个字符串总能保证 ( C 要求的)最后一个字符为零 ('\0') ,而且它允许在字符串内包含多个这样的零。

因为 Lua 中可能发生垃圾收集,所以不保证 lua_tolstring 返回的指针,在对应的值从堆栈中移除后依然有效。


lua_tonumber

[-0, +0, –]

  1. lua_Number lua_tonumber (lua_State *L, int index);

等价于调用 lua_tonumberx,其参数 isnumNULL


lua_tonumberx

[-0, +0, –]

  1. lua_Number lua_tonumberx (lua_State *L, int index, int *isnum);

把给定索引处的 Lua 值转换为 lua_Number 这样一个 C 类型(参见 lua_Number )。这个 Lua 值必须是一个数字或是一个可转换为数字的字符串 (参见 §3.4.3);否则, lua_tonumberx 返回 0 。

如果 isnum 不是 NULL*isnum 会被设为操作是否成功。


lua_topointer

[-0, +0, –]

  1. const void *lua_topointer (lua_State *L, int index);

把给定索引处的值转换为一般的 C 指针 (void*) 。这个值可以是一个用户对象,表 ,线程或是一个函数;否则, lua_topointer 返回 NULL 。不同的对象有不同的指针。不存在把指针再转回原有类型的方法。

这个函数通常只用于调试信息。


lua_tostring

[-0, +0, e]

  1. const char *lua_tostring (lua_State *L, int index);

等价于调用 lua_tolstring ,其参数 lenNULL


lua_tothread

[-0, +0, –]

  1. lua_State *lua_tothread (lua_State *L, int index);

把给定索引处的值转换为一个 Lua 线程(表示为 lua_State*)。这个值必须是一个线程;否则函数返回 NULL


lua_touserdata

[-0, +0, –]

  1. void *lua_touserdata (lua_State *L, int index);

如果给定索引处的值是一个完全用户数据,函数返回其内存块的地址。如果值是一个轻量用户数据,那么就返回它表示的指针。否则,返回 NULL


lua_type

[-0, +0, –]

  1. int lua_type (lua_State *L, int index);

返回给定有效索引处值的类型,当索引无效(或无法访问)时则返回 LUA_TNONElua_type 返回的类型被编码为一些个在lua.h 中定义的常量:LUA_TNILLUA_TNUMBERLUA_TBOOLEANLUA_TSTRINGLUA_TTABLELUA_TFUNCTIONLUA_TUSERDATALUA_TTHREADLUA_TLIGHTUSERDATA


lua_typename

[-0, +0, –]

  1. const char *lua_typename (lua_State *L, int tp);

返回 tp 表示的类型名,这个 tp 必须是 lua_type可能返回的值中之一。


lua_Unsigned

  1. typedef ... lua_Unsigned;

lua_Integer 的无符号版本。


lua_upvalueindex

[-0, +0, –]

  1. int lua_upvalueindex (int i);

返回当前运行的函数(参见 §4.4)的第 i 个上值的伪索引。


lua_version

[-0, +0, v]

  1. const lua_Number *lua_version (lua_State *L);

返回保存在 Lua 内核中储存的版本数字的地址。当调用时传入一个合法的 lua_State ,返回创建该状态机时的版本地址。如果用 NULL 调用,返回调用者的版本地址。


lua_Writer

  1. typedef int (*lua_Writer) (lua_State *L,
  2. const void* p,
  3. size_t sz,
  4. void* ud);

lua_dump 用到的写入器函数。每次 lua_dump 产生了一段新的代码块,它都会调用写入器。传入要写入的缓冲区 (p) 和它的尺寸 (sz) ,以及传给 lua_dump 的参数 data

写入器会返回一个错误码:0 表示没有错误; 别的值均表示一个错误,并且会让 lua_dump 停止再次调用写入器。


lua_xmove

[-?, +?, –]

  1. void lua_xmove (lua_State *from, lua_State *to, int n);

交换同一个状态机下不同线程中的值。

这个函数会从 from 的栈上弹出 n 个值,然后把它们压入 to 的栈上。


lua_yield

[-?, +?, e]

  1. int lua_yield (lua_State *L, int nresults);

这个函数等价于调用 lua_yieldk,不同的是不提供延续函数(参见 §4.7)。因此,当线程被延续,线程会继续运行调用 lua_yield 函数的函数。


lua_yieldk

[-?, +?, e]

  1. int lua_yieldk (lua_State *L,
  2. int nresults,
  3. lua_KContext ctx,
  4. lua_KFunction k);

让出协程(线程)。

当 C 函数调用了 lua_yieldk,当前运行的协程会挂起,启动这个线程的 lua_resume 调用返回。参数 nresults 指栈上需返回给lua_resume 的返回值的个数。

当协程再次被延续时,Lua 调用延续函数 k 继续运行被挂起(参见 §4.7)的 C 函数。延续函数会从前一个函数中接收到相同的栈,栈中的 n 个返回值被移除而压入了从lua_resume 传入的参数。此外,延续函数还会收到传给 lua_yieldk的参数 ctx

通常,这个函数不会返回;当协程一次次延续,将从延续函数继续运行。然而,有一个例外:当这个函数从一个逐行运行的钩子函数(参见 §4.9)中调用时,lua_yieldk 不可以提供延续函数。(也就是类似 lua_yield 的形式),而此时,钩子函数在调用完让出后将立刻返回。Lua 会使协程让出,一旦协程再次被延续,触发钩子的函数会继续正常运行。

当一个线程处于未提供延续函数的 C 调用中,调用它会抛出一个错误。从并非用延续方式(例如:主线程)启动的线程中调用它也会这样。