分类:
2013-01-24 09:36:34
原文地址:参考手册 - 3.7 - 函数与类型[A-I] 作者:hshq_cn
这儿我们按照字母顺序列出来自C API的所有函数和类型。每个函数有个类似这样的指示器:[-o, +p, x]
第一个字段,o
,是函数出栈多少个元素。第二个参数,p
,是函数入栈多少个元素。(所有的函数总是在将其参数出栈后将其结果入栈。)形如x|y
的字段意思是函数可能入栈(或出栈)x
或y
各元素,以来实际情形;一个问号标记‘?
’意思是我们不能通过察看其参数指导函数出栈/入栈多少元素(例如,它们可能依赖于栈中存储的情况)。第三个子段,x
,告知函数是否可能抛出错误:'-
' 意思是函数决不抛出任何错误;'m
' 意思是函数可能抛出一个错误,只取决于内存不足;'e
' 意思是函数可能抛出其他类型的错误;'v
' 意思是函数可能故意抛出错误。
typedef void * (*lua_Alloc) (void *ud,
void *ptr,
size_t osize,
size_t nsize);
这种类型的内存分配函数由Lua状态机使用。分配器函数必须提供类似realloc
的功能,但是不必完全一样。它的参数是ud
,一个由传入的不透明指针;ptr
,一个指向即将被分配/重分配/释放的内存块的指针;osize
,内存块原来的尺寸;nsize
,内存块的新尺寸。当且仅当osize
是0时ptr
为NULL
。当nsize
是0时,分配器必须返回NULL
;如果osize
非0,它将会释放ptr
指向的内存块。当nsize
非0时,当且仅当分配器不能满足请求时返回NULL
。当nsize
非0且osize
是0时,分配器应该表现的类似malloc
。当nsize
和osize
非0时,分配器表现的类似realloc
。Lua假定当osize >= nsize
时分配器决不失败。
这儿有个分配器函数的简单实现。它被辅助库中的被使用。
static void *l_alloc (void *ud, void *ptr, size_t osize,
size_t nsize) {
(void)ud; (void)osize; /* not used */
if (nsize == 0) {
free(ptr);
return NULL;
}
else
return realloc(ptr, nsize);
}
该代码假定free(NULL)
不起作用而且realloc(NULL, size)
等价于malloc(size)
。ANSI C确保这两种行为。
[-0, +0, -]
lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
设置新的应急(panic)函数并返回前一个。
如果在任何受保护的环境外面发生了错误,Lua调用应急函数接着调用exit(EXIT_FAILURE)
,从而退出宿主程序。你的应急函数可通过永不返回(例如执行一次长跳转)以避免这次退出。
应急函数可访问栈顶的错误消息。
[-(nargs + 1), +nresults, e]
void lua_call (lua_State *L, int nargs, int nresults);
调用一个函数。
要调用函数必须使用下面的协议:首先,将要被调用的函数压栈;然后,将函数参数顺序压栈;即第一参数首先压栈。最后,调用;nargs
是你压栈的参数数量。当函数被调用时所有参数以及函数值被弹出栈。当函数返回时其结果被压栈。结果被调整为nresults
个,除非nresults
是。在该情况下,来自函数的所有被压栈。Lua会确保返回值适合栈空间。函数结果被顺序压栈(第一个结果首先压栈),因而调用后最后一个参数在栈顶。
被调用函数内的任何错误会被向上传播(使用longjmp
)。
下面的例子显示宿主程序如何执行与该Lua代码等价的操作:
a = f("how", t.x, 14)
这是C中的代码:
lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* 要被调用的函数 */
lua_pushstring(L, "how"); /* 第1个参数 */
lua_getfield(L, LUA_GLOBALSINDEX, "t"); /* 要被索引的表 */
lua_getfield(L, -1, "x"); /* 将t.x的结果压栈(第2个参数) */
lua_remove(L, -2); /* 从栈中删除‘t’ */
lua_pushinteger(L, 14); /* 第3个参数 */
lua_call(L, 3, 1); /* 以3个参数调用‘f’,返回1个结果 */
lua_setfield(L, LUA_GLOBALSINDEX, "a"); /* 设置全局变量‘a’ */
注意上面的代码是“对称的”:在其结尾,栈回到其初始配置。这是一种良好的编程习惯。
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函数也能返回多个结果。
作为例子,下面的函数接收可变数量的数字参数,并返回它们的平均数与总和:
static int foo (lua_State *L) {
int n = lua_gettop(L); /* 参数的个数 */
lua_Number sum = 0;
int i;
for (i = 1; i <= n; i++) {
if (!lua_isnumber(L, i)) {
lua_pushstring(L, "incorrect argument");
lua_error(L);
}
sum += lua_tonumber(L, i);
}
lua_pushnumber(L, sum/n); /* 第1个参数 */
lua_pushnumber(L, sum); /* 第2个参数 */
return 2; /* 结果的个数 */
}
[-0, +0, m]
int lua_checkstack (lua_State *L, int extra);
确保栈中存在至少extra
个空闲栈槽位。如果栈不能增长到那个尺寸则返回假。本函数从不缩小栈;如果栈已经比新尺寸大则无变化。
[-0, +0, -]
void lua_close (lua_State *L);
销毁给定Lua状态机中的全部对象(如果存在对应的垃圾收集元方法则调用它们),并释放该状态机占用的所有动态内存。在一些平台上,你可能不需要调用本函 数,因为当宿主程序结束时,所有资源自然地被释放。另一方面,长期运行的程序,比如后台程序(daemon)或web服务器,可能需要在状态机不再需要时 立刻释放它们,以避免增长过大。
[-n, +1, e]
void lua_concat (lua_State *L, int n);
连接栈定的n
个值,弹出它们并将结果留在栈顶。如果n
是1,结果就是栈上的单个值(即函数什么也不做);如果n
是0,结果是空字符串。连接操作依照Lua的常规语义执行(见)。
[-0, +(0|1), -]
int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);
以保护模式调用C函数func
。func
的栈中只有一个元素,是个包含ud
的轻量级用户数据。发生错误时,返回同一样的错误代码,以及栈顶的错误对象;否则返回0且不改变栈。func
返回的所有值被丢弃。
[-0, +1, m]
void lua_createtable (lua_State *L, int narr, int nrec);
创建新的空表并将其压栈。新表预分配narr
个数组元素和nrec
个非数组元素的空闲空间。当你确切地知道表将由多少个元素时,预分配是非常有用的。否则,你可用函数。
[-0, +0, m]
int lua_dump (lua_State *L, lua_Writer writer, void *data);
将函数转储为二进制代码单元。接收栈顶的Lua函数并产生二进制单元,如果后者被再次加载,得到与被转储的等价的函数。当产生单元的各部分时,用给定的data
调用函数writer
(见)来写出它们。
返回值是最后一次调用记录器(writer)返回的错误代码;0表示没有错误。
本函数不会将Lua函数从栈中弹出。
[-0, +0, e]
int lua_equal (lua_State *L, int index1, int index2);
沿用Lua的==
操作符的语义(即可能调用元方法),比较在可接受索引index1
和index2
中的两个值,如果相等则返回1。否则返回0。如果任何索引无效也返回0。
[-1, +0, v]
int lua_error (lua_State *L);
产生一个Lua错误。错误消息(实际上可为任何类型的Lua值)必须在栈顶。本函数执行长跳转,因此从不返回。(见)。
[-0, +0, e]
int lua_gc (lua_State *L, int what, int data);
控制垃圾收集器。
本函数根据参数what
的值执行若干任务:
LUA_GCSTOP
: 停止垃圾收集器。
LUA_GCRESTART
: 重新启动垃圾收集器。
LUA_GCCOLLECT
: 执行一次完整的垃圾收集器周期。
LUA_GCCOUNT
: 返回Lua当前占用的内存总量(以Kbyte为单位)。
LUA_GCCOUNTB
: 返回Lua当前的内存用量的字节数除1024的余数。
LUA_GCSTEP
: 执行一步增量垃圾收集。步“长”由data
以未指定的方式控制(值越大意味着步骤越多)。要控制步长,你必须实验性地调整data
的值。如果该步完成了一个垃圾收集周期则函数返回1。
LUA_GCSETPAUSE
: 设置data
/100作为收集器的pause(见)的新值。返回pause的前一个值。
LUA_GCSETSTEPMUL
: 设置data
/100作为收集器的step multiplier(见)的新值。返回step multiplier的前一个值。
[-0, +0, -]
lua_Alloc lua_getallocf (lua_State *L, void **ud);
返回给定状态机的内存分配函数。如果ud
不为NULL
,Lua将传入的不透明指针存入*ud
。
[-0, +1, -]
void lua_getfenv (lua_State *L, int index);
将给定索引处的值的环境表压栈。
[-0, +1, e]
void lua_getfield (lua_State *L, int index, const char *k);
将t[k]
的值压栈,其中t
是给定的有效索引处的值。同Lua中一样,本函数可能触发用于“index”事件的元方法(见)。
[-0, +1, e]
void lua_getglobal (lua_State *L, const char *name);
将全局变量name
的值压栈。它被定义为宏:
#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, s)
[-0, +(0|1), -]
int lua_getmetatable (lua_State *L, int index);
将给定的认可的索引处的值的元表压栈。如果索引无效,或者如果该值没有元表,本函数返回0且不会压栈任何东西。
[-1, +1, e]
void lua_gettable (lua_State *L, int index);
将值t[k]
压栈,其中t
是指定的有效索引处的值,并且k
是栈顶的值。
本函数将键出栈(将结果值放在它的位置)。同Lua中一样,本函数可能触发用于“index”事件的元方法(见)。
[-0, +0, -]
int lua_gettop (lua_State *L);
返回栈顶元素的索引。因为索引从1开始,该结果等于栈中元素的数量(所以0表示空栈)。
[-1, +1, -]
void lua_insert (lua_State *L, int index);
将栈顶元素移入给定的有效索引,并将该索引上面的元素上移至开放空间。不能以伪索引调用,因为伪索引不是真实的栈位置。
typedef ptrdiff_t lua_Integer;
被Lua API用来表示整型值的类型。
缺省是ptrdiff_t
,它通常是是机器能处理的最大的带符号整型。
[-0, +0, -]
int lua_isboolean (lua_State *L, int index);
如果给定的认可的索引处的值具有布尔类型则返回1,否则返回0。
[-0, +0, -]
int lua_iscfunction (lua_State *L, int index);
如果给定的认可的索引处的值是C函数则返回1,否则返回0。
[-0, +0, -]
int lua_isfunction (lua_State *L, int index);
如果给定的认可的索引处的值是函数(C或Lua)则返回1,否则返回0。
[-0, +0, -]
int lua_islightuserdata (lua_State *L, int index);
如果给定的认可的索引处的值是轻型用户数据则返回1,否则返回0。
[-0, +0, -]
int lua_isnil (lua_State *L, int index);
如果给定的认可的索引处的值是nil则返回1,否则返回0。
[-0, +0, -]
int lua_isnone (lua_State *L, int index);
如果给定的认可的索引处的值不合法(即其引用当前栈外部的元素)则返回1,否则返回0。
[-0, +0, -]
int lua_isnoneornil (lua_State *L, int index);
如果给定的认可的索引处的值不合法(即其引用当前栈外部的元素)或该索引处的值是nil则返回1,否则返回0。
[-0, +0, -]
int lua_isnumber (lua_State *L, int index);
如果给定的认可的索引处的值是数字或者可转为数字的字符串则返回1,否则返回0。
[-0, +0, -]
int lua_isstring (lua_State *L, int index);
如果给定的认可的索引处的值是字符串或数字(它总是可转为字符串)则返回1,否则返回0。
[-0, +0, -]
int lua_istable (lua_State *L, int index);
如果给定的认可的索引处的值是表则返回1,否则返回0。
[-0, +0, -]
int lua_isthread (lua_State *L, int index);
如果给定的认可的索引处的值是线程则返回1,否则返回0。
[-0, +0, -]
int lua_isuserdata (lua_State *L, int index);
如果给定的认可的索引处的值是用户数据(完整的或轻型的)则返回1,否则返回0。