Lua5.3——C API函数

<span style="font-size:18px;">这里按字母次序列出了所有C API中的函数和类型。每个函数都有一个这样的提示:[-o, +p, x]
	对于第一个域,o,指的是该函数会从栈上弹出多少个元素。第二个域,p,指该函数会将多少个元素压栈。(所有函数都会在弹出参数后再把结果压栈。) x|y 这种形式的域表示该函数根据具体情况可能压入(或弹出) x 或 y 个元素;问号 '?' 表示 我们无法仅通过参数来了解该函数会弹出/压入多少元素 (比如,数量取决于栈上有些什么)。第三个域,x, 解释了该函数是否会抛出错误:'-' 表示该函数绝对不会抛出错误; 'e' 表示该函数可能抛出错误; 'v' 表示该函数可能抛出有意义的错误。
1、lua_absindex             [-0, +0, –]
	int lua_absindex (lua_State *L, int idx);
将一个可接受的索引 idx 转换为绝对索引 (即,一个不依赖栈顶在哪的值)。
2、lua_Alloc
	typedef void * (*lua_Alloc) (void *ud,void *ptr,size_t osize,size_t nsize);
Lua 状态机中使用的内存分配器函数的类型。 内存分配函数必须提供一个功能类似于 realloc 但又不完全相同的函数。
	它的参数有ud,一个由lua_newstate传给它的指针;ptr,一个指向已分配出来/将被重新分配/要释放的内存块指针;
	osize,内存块原来的尺寸或是关于什么将被分配出来的代码;nsize,新内存块的尺寸。如果ptr不是NULL,osize是ptr指向的内存块的尺寸,即这个内存块当初被分配或重分配的尺寸。
	如果ptr是NULL,osize是Lua即将分配对象类型的编码。当(且仅当)Lua创建一个对应类型的新对象时,osize是LUA_TSTRING,LUA_TTABLE,LUA_TFUNCTION,LUA_TUSERDATA,或LUA_TTHREAD 中的一个。若osize是其它类型,Lua将为其它东西分配内存。
Lua假定分配器函数会遵循以下行为:
	当nsize是零时,分配器必须和free行为类似并返回NULL。
	当nsize不是零时,分配器必须和realloc行为类似。如果分配器无法完成请求,返回NULL。Lua假定在osize>=nsize成立的条件下,分配器绝不会失败。这里有一个简单的分配器函数的实现。这个实现被放在补充库中,供luaL_newstate使用。
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);
     }
     注意,标准C能确保free(NULL)没有副作用,且realloc(NULL,size)等价于malloc(size)。这段代码假定realloc在缩小块长度时不会失败。(虽然标准C没有对此行为做出保证,但这看起来是一个安全的假定。)
3、lua_arith                               [-(2|1), +1, e]
	void lua_arith(lua_State *L, int op);
对栈顶的两个值(或者一个,比如取反)做一次数学或位操作。其中,栈顶的那个值是第二个操作数。它会弹出压入的值,并把结果放在栈顶。这个函数遵循Lua对应的操作符运算规则(即有可能触发元方法)。
op 的值必须是下列常量中的一个:
	LUA_OPADD:加法 (+)   			LUA_OPSUB:减法 (-)
LUA_OPMUL: 乘法 (*)				LUA_OPDIV: 浮点除法 (/)
LUA_OPMOD: 取模 (%) 			LUA_OPIDIV:向下取整的除法 (//)
LUA_OPPOW:乘方 (^)   			LUA_OPUNM:取负(一元 -)
LUA_OPBNOT:按位取反(~)			LUA_OPBAND:按位与(&)
LUA_OPBOR:按位或(|)   			LUA_OPBXOR:按位异或(~)
LUA_OPSHL:左移(<<)  				LUA_OPSHR:右移(>>)
4、lua_atpanic               [-0, +0, –]
	lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
设置一个新的 panic 函数,并返回之前设置的那个。
5、lua_call                     [-(nargs+1), +nresults, e]
	void lua_call (lua_State *L, int nargs, int nresults);
调用一个函数。要调用一个函数请遵循以下协议:
首先,要调用的函数应该被压入栈;接着,把需要传递给这个函数的参数按正序压栈;这是指第一个参数首先压栈。最后调用一下lua_call;nargs是你压入栈的参数个数。当函数调用完毕后,所有的参数以及函数本身都会出栈。而函数的返回值这时则被压栈。返回值的个数将被调整为nresults个,除非nresults被设置成LUA_MULTRET。在这种情况下,所有的返回值都被压入堆栈中。Lua会保证返回值都放入栈空间中。函数返回值将按正序压栈(第一个返回值首先压栈),因此在调用结束后,最后一个返回值将被放在栈顶。被调用函数内发生的错误将(通过 longjmp )一直上抛。下面的例子中,这行 Lua 代码等价于在宿主程序中用 C 代码做一些工作:
     a = f("how", t.x, 14)
    这里是 C 里的代码:
     lua_getglobal(L, "f");                  /* function to be called */
     lua_pushliteral(L, "how");                       /* 1st argument */
     lua_getglobal(L, "t");                    /* table to be indexed */
     lua_getfield(L, -1, "x");        /* push result of t.x (2nd arg) */
     lua_remove(L, -2);                  /* remove 't' from the stack */
     lua_pushinteger(L, 14);                          /* 3rd argument */
     lua_call(L, 3, 1);     /* call 'f' with 3 arguments and 1 result */
     lua_setglobal(L, "a");                         /* set global 'a' */
注意上面这段代码是平衡的:到了最后,堆栈恢复成原有的配置。这是一种良好的编程习惯。
6、lua_callk                       [-(nargs + 1), +nresults, e]
	void lua_callk (lua_State *L,int nargs,int nresults,lua_KContext ctx,lua_KFunction k);
这个函数的行为和lua_call完全一致,只不过它还允许被调用的函数让出。
7、lua_CFunction
	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.0;
       int i;
       for (i = 1; i <= n; i++) {
         if (!lua_isnumber(L, i)) {
           lua_pushliteral(L, "incorrect argument");
           lua_error(L);
         }
         sum += lua_tonumber(L, i);
       }
       lua_pushnumber(L, sum/n);        /* 第一个返回值 */
       lua_pushnumber(L, sum);         /* 第二个返回值 */
       return 2;                   /* 返回值的个数 */
     }
8、lua_checkstack                                    [-0, +0, –]
	int lua_checkstack(lua_State *L, int n);
确保堆栈上至少有n个额外空位。如果不能把堆栈扩展到相应的尺寸,函数返回假。失败的原因包括将把栈扩展到比固定最大尺寸还大(至少是几千个元素)或分配内存失败。这个函数永远不会缩小堆栈;如果堆栈已经比需要的大了,那么就保持原样。
9、lua_close                  [-0, +0, –]
	void lua_close (lua_State *L);
销毁指定Lua状态机中的所有对象(如果有垃圾收集相关的元方法的话,会调用它们),并且释放状态机中使用的所有动态内存。在一些平台上,你可以不必调用这个函数,因为当宿主程序结束的时候,所有的资源就自然被释放掉了。另一方面,长期运行的程序,比如一个后台程序或是一个网站服务器,会创建出多个Lua状态机。那么就应该在不需要时赶紧关闭它们。
10、lua_compare               [-0, +0, e]
	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:小于等于比较(<=)
11、lua_concat                [-n, +1, e]
	void lua_concat (lua_State *L, int n);
连接栈顶的n个值,然后将这些值出栈,并把结果放在栈顶。如果n为1,结果就是那个值放在栈上(即,函数什么都不做;)如果n为0,结果是一个空串。连接依照Lua中通常语义完成。
12、lua_copy                  [-0, +0, –]
	void lua_copy (lua_State *L, int fromidx, int toidx);
从索引fromidx处复制一个值到一个有效索引toidx处,覆盖那里的原有值。不会影响其它位置的值。
13、lua_createtable           [-0, +1, e]
	void lua_createtable (lua_State *L, int narr, int nrec);
创建一张新的空表压栈。参数narr建议了这张表作为序列使用时会有多少个元素;参数nrec建议了这张表可能拥有多少序列之外的元素。Lua会使用这些建议来预分配这张新表。如果你知道这张表用途的更多信息,预分配可以提高性能。否则,你可以使用函数lua_newtable 。
14、lua_dump                  [-0, +0, e]
	int lua_dump (lua_State *L,lua_Writer writer,void *data,int strip);
把函数导出成二进制代码块。函数接收栈顶的Lua函数做参数,然后生成它的二进制代码块。若被导出的东西被再次加载,加载的结果就相当于原来的函数。当它在产生代码块的时候,lua_dump通过调用函数writer(参见lua_Writer)来写入数据,后面的data参数会被传入writer。如果strip为真,二进制代码块将不包含该函数的调试信息。最后一次由writer的返回值将作为这个函数的返回值返回;0表示没有错误。该函数不会把Lua函数弹出堆栈。
15、lua_error                 [-1, +0, v]
	int lua_error (lua_State *L);
以栈顶的值作为错误对象,抛出一个Lua错误。这个函数将做一次长跳转,所以一定不会返回。
16、lua_gc                    [-0, +0, e]
	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_GCISRUNNING:返回收集器是否在运行(即没有停止)。
	LUA_GCSETPAUSE: 把 data 设为 垃圾收集器间歇率,并返回之前设置的值。
	LUA_GCSETSTEPMUL: 把data设为垃圾收集器步进倍率,并返回之前设置的值。
17、lua_getallocf              [-0, +0, –]
	lua_Alloc lua_getallocf (lua_State *L, void **ud);
返回给定状态机的内存分配器函数。如果ud不是NULL,Lua把设置内存分配函数时设置的那个指针置入*ud。
18、lua_getfield               [-0, +1, e]
	int lua_getfield (lua_State *L, int index, const char *k);
把 t[k] 的值压栈,这里的t是索引指向的值。在Lua中,这个函数可能触发对应"index"事件对应的元方法。函数将返回压入值的类型。
19、lua_getextraspace          [-0, +0, –]
	void *lua_getextraspace (lua_State *L);
返回一个Lua状态机中关联的内存块指针。程序可以把这块内存用于任何用途;而Lua不会使用它。每一个新线程都会携带一块内存,初始化为主线程的这块内存的副本。
默认配置下,这块内存的大小为空指针的大小。不过你可以重新编译Lua设定这块内存不同的大小。
20、lua_getglobal              [-0, +1, e]
	int lua_getglobal (lua_State *L, const char *name);
把全局变量name里的值压栈,返回该值的类型。
21、lua_geti                   [-0, +1, e]
	int lua_geti (lua_State *L, int index, lua_Integer i);
把t[i]的值压栈,这里的t指给定的索引指代的值。和在Lua里一样,这个函数可能会触发"index"事件的元方法。返回压入值的类型。
22、lua_getmetatable               [-0, +(0|1), –]
	int lua_getmetatable (lua_State *L, int index);
如果该索引处的值有元表,则将其元表压栈,返回 1 。 否则不会将任何东西入栈,返回 0 。
23、lua_gettable                  [-1, +1, e]
	int lua_gettable (lua_State *L, int index);
把t[k]的值压栈,这里的t是指索引指向的值,而k则是栈顶放的值。
这个函数会弹出堆栈上的键,把结果放在栈上相同位置。和在Lua中一样,这个函数可能触发对应"index"事件的元方法。返回压入值的类型。
24、lua_gettop                    [-0, +0, –]
	int lua_gettop (lua_State *L);
返回栈顶元素的索引。因为索引是从1开始编号的,所以这个结果等于栈上的元素个数;特别指出,0表示栈为空。
25、lua_getuservalue              [-0, +1, –]
	int lua_getuservalue (lua_State *L, int index);
将给定索引处的用户数据所关联的Lua值压栈。返回压入值的类型。
26、lua_insert                   [-1, +1, –]
	void lua_insert (lua_State *L, int index);
把栈顶元素移动到指定的有效索引处,依次移动这个索引之上的元素。不要用伪索引来调用这个函数,因为伪索引没有真正指向栈上的位置。
27、lua_Integer
	typedef ... lua_Integer;
Lua 中的整数类型。缺省时,这个就是long long,(通常是一个64位以二为补码的整数),也可以修改它为long或int(通常是一个32位以二为补码的整数)。Lua 定义了两个常量:LUA_MININTEGER和LUA_MAXINTEGER来表示这个类型可以表示的最小和最大值。
28、lua_isboolean                [-0, +0, –]
	int lua_isboolean (lua_State *L, int index);
当给定索引的值是一个布尔量时,返回 1,否则返回 0。
29、lua_iscfunction              [-0, +0, –]
	int lua_iscfunction (lua_State *L, int index);
当给定索引的值是一个 C 函数时,返回 1 ,否则返回 0 。
30、lua_isfunction               [-0, +0, –]
	int lua_isfunction (lua_State *L, int index);
当给定索引的值是一个函数(C或Lua函数均可)时,返回1,否则返回0。
31、lua_isinteger                [-0, +0, –]
	int lua_isinteger (lua_State *L, int index);
当给定索引的值是一个整数(其值是一个数字,且内部以整数储存),时,返回1,否则返回0。
32、lua_islightuserdata          [-0, +0, –]
	int lua_islightuserdata (lua_State *L, int index);
当给定索引的值是一个轻量用户数据时,返回 1 ,否则返回 0 。
33、lua_isnil                    [-0, +0, –]
	int lua_isnil (lua_State *L, int index);
当给定索引的值是 nil 时,返回 1,否则返回0。
34、lua_isnone                   [-0, +0, –]
	int lua_isnone (lua_State *L, int index);
	当给定索引无效时,返回 1 ,否则返回 0 。
35、lua_isnoneornil              [-0, +0, –]
	int lua_isnoneornil (lua_State *L, int index);
	当给定索引无效或其值是 nil 时, 返回 1 ,否则返回 0 。
36、lua_isnumber                 [-0, +0, –]
	int lua_isnumber (lua_State *L, int index);
当给定索引的值是一个数字,或是一个可转换为数字的字符串时,返回 1 ,否则返回 0 。
37、lua_isstring                 [-0, +0, –]
	int lua_isstring (lua_State *L, int index);
当给定索引的值是一个字符串或是一个数字(数字总能转换成字符串)时,返回1,否则返回0。
38、lua_istable                  [-0, +0, –]
	int lua_istable (lua_State *L, int index);
	当给定索引的值是一张表时,返回 1 ,否则返回 0 。
39、lua_isthread                 [-0, +0, –]
	int lua_isthread (lua_State *L, int index);
	当给定索引的值是一条线程时,返回 1 ,否则返回 0 。
40、lua_isuserdata               [-0, +0, –]
	int lua_isuserdata (lua_State *L, int index);
当给定索引的值是一个用户数据(无论是完全的还是轻量的)时,返回1,否则返回0。
41、lua_isyieldable              [-0, +0, –]
	int lua_isyieldable (lua_State *L);
	如果给定的协程可以让出,返回 1 ,否则返回 0 。
42、lua_KContext
	typedef ... lua_KContext;
延续函数上下文参数的类型。这一定是一个数字类型。当有intptr_t时,被定义为intptr_t,因此它也可以保存指针。否则,它被定义为 ptrdiff_t。
43、lua_KFunction
	typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);
	延续函数的类型。
44、lua_len                      [-0, +1, e]
	void lua_len (lua_State *L, int index);
	返回给定索引的值的长度。它等价于Lua中的 '#' 操作符。它有可能触发 "length" 事件对应的元方法。结果压栈。
45、lua_load                     [-0, +1, –]
	int lua_load (lua_State *L,lua_Reader reader,void *data,const char *chunkname, const char *mode);
	加载一段Lua代码块,但不运行它。如果没有错误,lua_load把一个编译好的代码块作为一个Lua函数压到栈顶。否则,压入错误消息。
	lua_load 的返回值可以是:
		LUA_OK:没有错误;	LUA_ERRSYNTAX: 在预编译时碰到语法错误;
LUA_ERRMEM: 内存分配错误;LUA_ERRGCMM: 在运行 __gc 元方法时出错了。 	(这个错误和代码块加载过程无关,它是由垃圾收集器引发的。)
lua_load函数使用一个用户提供的reader函数来读取代码块。data参数会被传入reader函数。
chunkname 这个参数可以赋予代码块一个名字, 这个名字被用于出错信息和调试信息。
lua_load会自动检测代码块是文本的还是二进制的, 然后做对应的加载操作。字符串 mode的作用和函数load一致。它还可以是NULL等价于字符串"bt"。
lua_load的内部会使用栈,因此reader函数必须永远在每次返回时保留栈的原样。
如果返回的函数有上值,第一个上值会被设置为保存在注册表LUA_RIDX_GLOBALS索引处的全局环境。在加载主代码块时,这个上值是_ENV变量。其它上值均被初始化为nil。
46、lua_newstate                  [-0, +0, –]
	lua_State *lua_newstate (lua_Alloc f, void *ud);
创建一个运行在新的独立的状态机中的线程。如果无法创建线程或状态机(由于内存有限)则返回 NULL。参数f是一个分配器函数;Lua将通过这个函数做状态机内所有的内存分配操作。第二个参数ud,这个指针将在每次调用分配器时被转入。
47、lua_newtable                   [-0, +1, e]
	void lua_newtable (lua_State *L);
	创建一张空表,并将其压栈。它等价于 lua_createtable(L, 0, 0) 。
48、lua_newthread                  [-0, +1, e]
	lua_State *lua_newthread (lua_State *L);
创建一条新线程,并将其压栈,并返回维护这个线程的lua_State 指针。这个函数返回的新线程共享原线程的全局环境,但是它有独立的运行栈。没有显式的函数可以用来关闭或销毁掉一个线程。线程跟其它Lua对象一样是垃圾收集的条目之一。
49、lua_newuserdata                [-0, +1, e]
	void *lua_newuserdata (lua_State *L, size_t size);
这个函数分配一块指定大小的内存块,把内存块地址作为一个完全用户数据压栈,并返回这个地址。宿主程序可以随意使用这块内存。
50、lua_next                       [-1, +(2|0), e]
	int lua_next (lua_State *L, int index);
从栈顶弹出一个键,然后把索引指定的表中的一个键值对压栈(弹出的键之后的 “下一” 对)。如果表中以无更多元素,那么lua_next 将返回 0 (什么也不压栈)。
典型的遍历方法是这样的:
     /*  表放在索引 't' 处 */
     lua_pushnil(L);  /* 第一个键 */
     while (lua_next(L, t) != 0) {
       /* 使用 '键' (在索引 -2 处) 和 '值' (在索引 -1 处)*/
       printf("%s - %s\n",
              lua_typename(L, lua_type(L, -2)),
              lua_typename(L, lua_type(L, -1)));
       /* 移除 '值' ;保留 '键' 做下一次迭代 */
       lua_pop(L, 1);
     }
在遍历一张表的时候,不要直接对键调用lua_tolstring,除非你知道这个键一定是一个字符串。调用lua_tolstring有可能改变给定索引位置的值;这会对下一次调用lua_next造成影响。关于迭代过程中修改被迭代的表的注意事项参见 next 函数。
51、lua_Number
	typedef double lua_Number;
	Lua 中浮点数的类型。Lua 中数字的类型。缺省是double但是你可以改成float。
52、lua_numbertointeger
	int lua_numbertointeger (lua_Number n, lua_Integer *p);
将一个Lua浮点数转换为一个Lua整数。这个宏假设n有对应的整数值。如果该值在Lua整数可表示范围内,就将其转换为一个整数赋给*p。宏的结果是一个布尔量,表示转换是否成功。(注意、由于圆整关系,这个范围测试不用此宏很难做对。)该宏有可能对其参数做多次取值。
53、lua_pcall                     [-(nargs + 1), +(nresults|1), –]
	int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);
以保护模式调用一个函数。
nargs和nresults 的含义与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 元方法时发生的错误。(这个错误和被调用的函数无关。)
54、lua_pcallk                     [-(nargs + 1), +(nresults|1), –]
	int lua_pcallk (lua_State *L,int nargs, int nresults, int msgh, lua_KContext ctx,lua_KFunction k);
	这个函数的行为和 lua_pcall 完全一致,只不过它还允许被调用的函数让出
55、lua_pop                         [-n, +0, –]
	void lua_pop (lua_State *L, int n);
	从栈中弹出 n 个元素。
56、lua_pushboolean                 [-0, +1, –]
	void lua_pushboolean (lua_State *L, int b);
	把 b 作为一个布尔量压栈。
57、lua_pushcclosure                 [-n, +1, e]
	void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
把一个新的C闭包压栈。当创建了一个C函数后,你可以给它关联一些值,这就是在创建一个C闭包;接下来无论函数何时被调用,这些值都可以被这个函数访问到。为了将一些值关联到一个C函数上,首先这些值需要先被压入堆栈(如果有多个值,第一个先压)。接下来调用lua_pushcclosure来创建出闭包并把这个C函数压到栈上。参数n告之函数有多少个值需要关联到函数上。lua_pushcclosure 也会把这些值从栈上弹出。n的最大值是 255。当n为零时,这个函数将创建出一个轻量C函数,它就是一个指向C函数的指针。这种情况下,不可能抛出内存错误。
58、lua_pushcfunction                [-0, +1, –]
	void lua_pushcfunction (lua_State *L, lua_CFunction f);
将一个C函数压栈。这个函数接收一个C函数指针,并将一个类型为 function 的Lua值压栈。当这个栈顶的值被调用时,将触发对应的C函数。注册到Lua中的任何函数都必须遵循正确的协议来接收参数和返回值。
lua_pushcfunction 是作为一个宏定义出现的:
     #define lua_pushcfunction(L,f)  lua_pushcclosure(L,f,0)
59、lua_pushfstring                  [-0, +1, e]
	const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
把一个格式化过的字符串压栈,然后返回这个字符串的指针。它和C函数sprintf比较像,不过有一些重要的区别:你不需要为结果分配空间:其结果是一个Lua 字符串,由Lua来关心其内存分配(同时通过垃圾收集来释放内存)。这个转换非常的受限。不支持符号、宽度、精度。转换符只支持'%%'(插入一个字符 '%'),'%s'(插入一个带零终止符的字符串,没有长度限制),'%f'(插入一个lua_Number),'%L'(插入一个lua_Integer),'%p'(插入一个指针或是一个十六进制数),'%d'(插入一个 int),'%c'(插入一个用int表示的单字节字符),以及'%U'(插入一个用long int 表示的UTF-8 字)。
60、lua_pushglobaltable              [-0, +1, –]
	void lua_pushglobaltable (lua_State *L);
将全局环境压栈。
61、lua_pushinteger                  [-0, +1, –]
	void lua_pushinteger (lua_State *L, lua_Integer n);
把值为 n 的整数压栈。
62、lua_pushlightuserdata            [-0, +1, –]
	void lua_pushlightuserdata (lua_State *L, void *p);
把一个轻量用户数据压栈。
用户数据是保留在Lua中的C值。轻量用户数据表示一个指针void*。它是一个像数字一样的值:你不需要专门创建它,它也没有独立的元表,而且也不会被收集(因为从来不需要创建)。只要表示的C地址相同,两个轻量用户数据就相等。
63、lua_pushliteral                  [-0, +1, e]
	const char *lua_pushliteral (lua_State *L, const char *s);
这个宏等价于 lua_pushlstring, 区别仅在于只能在 s 是一个字面量时才能用它。 它会自动给出字符串的长度。
64、lua_pushlstring                  [-0, +1, e]
	const char *lua_pushlstring (lua_State *L, const char *s, size_t len);
把指针 s 指向的长度为 len 的字符串压栈。Lua 对这个字符串做一个内部副本(或是复用一个副本),因此s处的内存在函数返回后,可以释放掉或是立刻重用于其它用途。 字符串内可以是任意二进制数据,包括零字符。返回内部副本的指针。
65、lua_pushnil                      [-0, +1, –]
	void lua_pushnil (lua_State *L);
将空值压栈。
66、lua_pushnumber                   [-0, +1, –]
	void lua_pushnumber (lua_State *L, lua_Number n);
把一个值为 n 的浮点数压栈。
67、lua_pushstring                   [-0, +1, e]
	const char *lua_pushstring (lua_State *L, const char *s);
将指针 s 指向的零结尾的字符串压栈。 因此 s 处的内存在函数返回后,可以释放掉或是立刻重用于其它用途。返回内部副本的指针。如果 s 为 NULL,将 nil 压栈并返回 NULL。
68、lua_pushthread                   [-0, +1, –]
	int lua_pushthread (lua_State *L);
把 L 表示的线程压栈。 如果这个线程是当前状态机的主线程的话,返回 1 。
69、lua_pushvalue                    [-0, +1, –]
	void lua_pushvalue (lua_State *L, int index);
把栈上给定索引处的元素作一个副本压栈。
70、lua_pushvfstring                 [-0, +1, e]
	const char *lua_pushvfstring (lua_State *L,const char *fmt,va_list argp);
等价于 lua_pushfstring, 不过是用 va_list 接收参数,而不是用可变数量的实际参数。
71、lua_rawequal                    [-0, +0, –]
	int lua_rawequal (lua_State *L, int index1, int index2);
如果索引index1与索引index2处的值本身相等(即不调用元方法),返回1。否则返回0。当任何一个索引无效时,也返回0。
72、lua_rawget                      [-1, +1, –]
	int lua_rawget (lua_State *L, int index);
类似于 lua_gettable , 但是作一次直接访问(不触发元方法)。
73、lua_rawgeti                     [-0, +1, –]
	int lua_rawgeti (lua_State *L, int index, lua_Integer n);
把 t[n] 的值压栈,这里的 t 是指给定索引处的表。这是一次直接访问;就是说,它不会触发元方法。返回入栈值的类型。
74、lua_rawgetp                     [-0, +1, –]
	int lua_rawgetp (lua_State *L, int index, const void *p);
把 t[k] 的值压栈,这里的t是指给定索引处的表,k是指针p对应的轻量用户数据。这是一次直接访问;就是说,它不会触发元方法。返回入栈值的类型。
75、lua_rawlen                      [-0, +0, –]
	size_t lua_rawlen (lua_State *L, int index);
返回给定索引处值的固有“长度”:对于字符串,它指字符串的长度;对于表;它指不触发元方法的情况下取长度操作('#')应得到的值; 对于用户数据,它指为该用户数据分配的内存块的大小; 对于其它值,它为 0 。
76、lua_rawset                     [-2, +0, e]
	void lua_rawset (lua_State *L, int index);
类似于 lua_settable , 但是是做一次直接赋值(不触发元方法)。
77、lua_rawseti                    [-1, +0, e]
	void lua_rawseti (lua_State *L, int index, lua_Integer i);
等价于t[i]=v,这里的t是指给定索引处的表,而v是栈顶的值。这个函数会将值弹出栈。赋值是直接的;即不会触发元方法。
78、lua_rawsetp                    [-1, +0, e]
	void lua_rawsetp (lua_State *L, int index, const void *p);
等价于 t[k] = v , 这里的 t 是指给定索引处的表, k 是指针 p 对应的轻量用户数据。 而 v 是栈顶的值。这个函数会将值弹出栈。 赋值是直接的;即不会触发元方法。
79、lua_Reader
	typedef const char * (*lua_Reader) (lua_State *L,  void *data, size_t *size);
lua_load用到的读取器函数,每次它需要一块新的代码块的时候,lua_load就调用读取器,每次都会传入一个参数data。读取器需要返回含有新的代码块的一块内存的指针,并把size设为这块内存的大小。内存块必须在下一次函数被调用之前一直存在。读取器可以通过返回NULL或设size为0来指示代码块结束。读取器可能返回多个块,每个块可以有任意的大于零的尺寸。
80、lua_register                   [-0, +0, e]
	void lua_register (lua_State *L, const char *name, lua_CFunction f);
把 C 函数 f 设到全局变量 name 中。 它通过一个宏定义:
 #define lua_register(L,n,f)             (lua_pushcfunction(L, f), lua_setglobal(L, n))
81、lua_remove                     [-1, +0, –]
	void lua_remove (lua_State *L, int index);
从给定有效索引处移除一个元素,把这个索引之上的所有元素移下来填补上这个空隙。不能用伪索引来调用这个函数,因为伪索引并不指向真实的栈上的位置。
82、lua_replace                    [-1, +0, –]
	void lua_replace (lua_State *L, int index);
把栈顶元素放置到给定位置而不移动其它元素 (因此覆盖了那个位置处的值),然后将栈顶元素弹出。
83、lua_resume                     [-?, +?, –]
	int lua_resume (lua_State *L, lua_State *from, int nargs);
在给定线程中启动或延续一条协程 。
要启动一个协程的话,你需要把主函数以及它需要的参数压入线程栈;然后调用lua_resume,把nargs设为参数的个数。这次调用会在协程挂起时或是结束运行后返回。当函数返回时,堆栈中会有传给lua_yield的所有值,或是主函数的所有返回值。
当协程让出,lua_resume返回LUA_YIELD,若协程结束运行且没有任何错误时,返回0。如果有错则返回错误代码。在发生错误的情况下,堆栈没有展开,因此你可以使用调试 API 来处理它。错误消息放在栈顶在。要延续一个协程,你需要清除上次 lua_yield 遗留下的所有结果,你把需要传给 yield 作结果的值压栈,然后调用 lua_resume 。参数from表示协程从哪个协程中来延续L的。如果不存在这样一个协程,这个参数可以是NULL 。
84、lua_rotate                    [-0, +0, –]
	void lua_rotate (lua_State *L, int idx, int n);
把从idx开始到栈顶的元素轮转n个位置。对于n为正数时,轮转方向是向栈顶的;当n为负数时,向栈底方向轮转-n个位置。n的绝对值不可以比参于轮转的切片长度大。
85、lua_setallocf                 [-0, +0, –]
	void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
把指定状态机的分配器函数换成带上用户数据 ud 的 f 。
86、lua_setfield                  [-1, +0, e]
	void lua_setfield (lua_State *L, int index, const char *k);
做一个等价于 t[k] = v 的操作, 这里 t 是给出的索引处的值, 而 v 是栈顶的那个值。
这个函数将把这个值弹出栈。 跟在 Lua 中一样,这个函数可能触发一个 "newindex" 事件的元方法。
87、lua_setglobal                 [-1, +0, e]
	void lua_setglobal (lua_State *L, const char *name);
从堆栈上弹出一个值,并将其设为全局变量 name 的新值。
88、lua_seti                      [-1, +0, e]
	void lua_seti (lua_State *L, int index, lua_Integer n);
做一个等价于 t[n] = v 的操作, 这里 t 是给出的索引处的值, 而 v 是栈顶的那个值。
这个函数将把这个值弹出栈。 跟在 Lua 中一样,这个函数可能触发一个 "newindex" 事件的元方法。
89、lua_setmetatable              [-1, +0, –]
	void lua_setmetatable (lua_State *L, int index);
把一张表弹出栈,并将其设为给定索引处的值的元表。
90、lua_settable                  [-2, +0, e]
	void lua_settable (lua_State *L, int index);
做一个等价于 t[k] = v 的操作, 这里 t 是给出的索引处的值, v 是栈顶的那个值, k 是栈顶之下的值。这个函数会将键和值都弹出栈。 跟在 Lua 中一样,这个函数可能触发一个 "newindex" 事件的元方法。
91、lua_settop                   [-?, +?, –]
	void lua_settop (lua_State *L, int index);
参数允许传入任何索引以及 0 。 它将把堆栈的栈顶设为这个索引。 如果新的栈顶比原来的大, 超出部分的新元素将被填为 nil 。 如果 index 为 0 , 把栈上所有元素移除。
92、lua_setuservalue             [-1, +0, –]
	void lua_setuservalue (lua_State *L, int index);
从栈上弹出一个值并将其设为给定索引处用户数据的关联值。
93、lua_State
	typedef struct lua_State lua_State;
一个不透明的结构,它指向一条线程并间接(通过该线程)引用了整个Lua解释器的状态。Lua库是完全可重入的:它没有任何全局变量。 状态机所有的信息都可以通过这个结构访问到。这个结构的指针必须作为第一个参数传递给每一个库函数。
lua_newstate 是一个例外, 这个函数会从头创建一个 Lua 状态机。
94、lua_status                   [-0, +0, –]
	int lua_status (lua_State *L);
返回线程 L 的状态。
正常的线程状态是 0 (LUA_OK)。 当线程用 lua_resume 执行完毕并抛出了一个错误时, 状态值是错误码。 如果线程被挂起,状态为 LUA_YIELD 。你只能在状态为 LUA_OK 的线程中调用函数。 你可以延续一个状态为 LUA_OK 的线程 (用于开始新协程)或是状态为 LUA_YIELD 的线程 (用于延续协程)。
95、lua_stringtonumber           [-0, +1, –]
	size_t lua_stringtonumber (lua_State *L, const char *s);
将一个零结尾的字符串 s 转换为一个数字,将这个数字压栈,并返回字符串的总长度(即长度加一)。转换的结果可能是整数也可能是浮点数,这取决于Lua的转换语法。这个字符串可以有前置和后置的空格以及符号。如果字符串并非一个有效的数字,返回 0 并不把任何东西压栈。(注意,这个结果可以当成一个布尔量使用,为真即转换成功。)
96、lua_toboolean                [-0, +0, –]
	int lua_toboolean (lua_State *L, int index);
把给定索引处的 Lua 值转换为一个 C中的布尔量(0 或是 1)。和Lua中做的所有测试一样,lua_toboolean会把任何不同于false 和 nil 的值当作真返回;否则就返回假。(如果你想只接收真正的 boolean 值,就需要使用 lua_isboolean 来测试值的类型。)
97、lua_tocfunction              [-0, +0, –]
	lua_CFunction lua_tocfunction (lua_State *L, int index);
把给定索引处的Lua值转换为一个C函数。这个值必须是一个C函数;如果不是就返回NULL。
98、lua_tointeger                [-0, +0, –]
	lua_Integer lua_tointeger (lua_State *L, int index);
等价于调用 lua_tointegerx, 其参数 isnum 为 NULL。
99、lua_tointegerx               [-0, +0, –]
	lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);
将给定索引处的 Lua 值转换为带符号的整数类型 lua_Integer。 这个 Lua 值必须是一个整数,或是一个可以被转换为整数的数字或字符串; 否则,lua_tointegerx 返回 0 。如果 isnum 不是 NULL, *isnum 会被设为操作是否成功。
100、lua_tolstring               [-0, +0, e]
	const char *lua_tolstring (lua_State *L, int index, size_t *len);
把给定索引处的Lua值转换为一个C字符串。如果len不为NULL,它还把字符串长度设到 *len中。这个Lua值必须是一个字符串或是一个数字;否则返回返回NULL。如果值是一个数字,lua_tolstring还会 把堆栈中的那个值的实际类型转换为一个字符串。(当遍历一张表的时候,若把lua_tolstring作用在键上,这个转换有可能导致lua_next弄错。)lua_tolstring 返回一个已对齐指针指向Lua状态机中的字符串。这个字符串总能保证(C要求的)最后一个字符为零('\0'),而且它允许在字符串内包含多个这样的零。因为 Lua中可能发生垃圾收集,所以不保证lua_tolstring返回的指针,在对应的值从堆栈中移除后依然有效。
101、lua_tonumber                 [-0, +0, –]
	lua_Number lua_tonumber (lua_State *L, int index);
等价于调用 lua_tonumberx, 其参数 isnum 为 NULL。
102、lua_tonumberx                 [-0, +0, –]
	lua_Number lua_tonumberx (lua_State *L, int index, int *isnum);
把给定索引处的Lua值转换为lua_Number这样一个C类型。这个Lua值必须是一个数字或是一个可转换为数字的字符串;否则,lua_tonumberx 返回0。如果isnum不是NULL,*isnum会被设为操作是否成功。
103、lua_topointer                 [-0, +0, –]
	const void *lua_topointer (lua_State *L, int index);
把给定索引处的值转换为一般的C指针(void*)。这个值可以是一个用户对象,表,线程或是一个函数;否则,lua_topointer返回NULL。不同的对象有不同的指针。不存在把指针再转回原有类型的方法。这个函数通常只用于调试信息。
104、lua_tostring                  [-0, +0, e]
	const char *lua_tostring (lua_State *L, int index);
等价于调用 lua_tolstring , 其参数 len 为 NULL 。
105、lua_tothread                  [-0, +0, –]
	lua_State *lua_tothread (lua_State *L, int index);
把给定索引处的值转换为一个Lua线程(表示为lua_State*)。这个值必须是一个线程;否则函数返回NULL。
106、lua_touserdata                [-0, +0, –]
	void *lua_touserdata (lua_State *L, int index);
如果给定索引处的值是一个完全用户数据,函数返回其内存块的地址。如果值是一个轻量用户数据,那么就返回它表示的指针。否则,返回NULL。
107、lua_type                      [-0, +0, –]
	int lua_type (lua_State *L, int index);
返回给定有效索引处值的类型,当索引无效(或无法访问)时则返回LUA_TNONE。lua_type返回的类型被编码为一些个在lua.h中定义的常量:LUA_TNIL,LUA_TNUMBER,LUA_TBOOLEAN,LUA_TSTRING,LUA_TTABLE,LUA_TFUNCTION,LUA_TUSERDATA,LUA_TTHREAD,LUA_TLIGHTUSERDATA。
108、lua_typename                  [-0, +0, –]
	const char *lua_typename (lua_State *L, int tp);
返回 tp 表示的类型名, 这个 tp 必须是 lua_type 可能返回的值中之一。
109、lua_Unsigned
	typedef ... lua_Unsigned;
lua_Integer 的无符号版本。
110、lua_upvalueindex              [-0, +0, –]
	int lua_upvalueindex (int i);
返回当前运行的函数(参见 §4.4)的第 i 个上值的伪索引。
111、lua_version                   [-0, +0, v]
	const lua_Number *lua_version (lua_State *L);
返回保存在Lua内核中储存的版本数字的地址。当调用时传入一个合法的lua_State,返回创建该状态机时的版本地址。如果用NULL调用,返回调用者的版本地址。
112、lua_Writer
	typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
被lua_dump用到的写入器函数。每次lua_dump产生了一段新的代码块,它都会调用写入器。传入要写入的缓冲区(p)和它的尺寸(sz),以及传给lua_dump的参数data。写入器会返回一个错误码 0 表示没有错误;别的值均表示一个错误,并且会让lua_dump 停止再次调用写入器。
113、lua_xmove                       [-?, +?, –]
	void lua_xmove (lua_State *from, lua_State *to, int n);
交换同一个状态机下不同线程中的值。这个函数会从from的栈上弹出n个值,然后把它们压入to的栈上。
114、lua_yield                       [-?, +?, e]
	int lua_yield (lua_State *L, int nresults);
这个函数等价于调用lua_yieldk,不同的是不提供延续函数。因此,当线程被延续,线程会继续运行调用lua_yield函数的函数。
115、lua_yieldk                      [-?, +?, e]
	int lua_yieldk (lua_State *L,int nresults,lua_KContext ctx, lua_KFunction k);
让出协程(线程)。
当C函数调用了lua_yieldk,当前运行的协程会挂起,启动这个线程的lua_resume调用返回。参数nresults指栈上需返回给lua_resume 的返回值的个数。
当协程再次被延续时,Lua调用延续函数k继续运行被挂起的C函数。延续函数会从前一个函数中接收到相同的栈,栈中的n个返回值被移除而压入了从lua_resume传入的参数。此外,延续函数还会收到传给lua_yieldk的参数 ctx。通常,这个函数不会返回;当协程一次次延续,将从延续函数继续运行。然而,有一个例外:当这个函数从一个逐行运行的钩子函数中调用时,lua_yieldk不可以提供延续函数。(也就是类似lua_yield的形式),而此时,钩子函数在调用完让出后将立刻返回。Lua会使协程让出,一旦协程再次被延续,触发钩子的函数会继续正常运行。当一个线程处于未提供延续函数的C调用中,调用它会抛出一个错误。从并非用延续方式(例如:主线程)启动的线程中调用它也会这样。
</span>

时间: 2024-09-29 18:25:59

Lua5.3——C API函数的相关文章

hash算法搜索获得api函数地址的实现

我们一般要获得一个函数的地址,通常采用的是明文,例如定义一个api函数字符串"MessageBoxA",然后在GetProcAddress函数中一个字节一个字节进行比较.这样弊端很多,例如如果我们定义一个杀毒软件比较敏感的api函数字符串,那么可能就会增加杀毒软件对我们的程序的判定值,而且定义这些字符串还有一个弊端是占用的字节数较大.我们想想如何我们的api函数字符串通过算法将它定义成一个4字节的值,然后在GetProcAddress中把AddressOfNames表中的每个地址指向的

Delphi获取当前系统时间(使用API函数GetSystemTime)

在开发应用程序时往往需要获取当前系统时间.尽管Y2K似乎已经平安过去,但在我们新开发的应用程序中还是要谨慎处理“时间”问题. 在<融会贯通--Delphi4.0实战技巧>(以下简称“该书”)第89页专门介绍了两种获取当前系统时间的方法,但这两种方法都存在不足或错误,以下就此进行讨论. 该书第一种方法是利用Time()函数获得当前系统时间,返回结果是TDateTime结构类型的变量.例如: procedure TForm1.Button2Click(Sender: TObject); var D

Delphi使用Windows API函数AnimateWindow实现窗体特效

{**********************************************************************API函数 AnimateWindow 使用:函数功能:窗体显示和隐藏时产生特殊的动画效果:可以产生两种类型的动画效果:          滚动动画 和 滑动动画函数原型:BOOL AnimateWindow(HWND hWnd, DWORD dwTime, DWORD dwFlags)参数说明:hWnd 指定产生动画效果的窗体的句柄:          

Vb.net/VB 声明API函数实现父窗体功能

回顾第一次敲机房收费,自己调用了api函数实现了父窗体及其子窗体最小化的功能,如今再次遇到,自己就在思考,能不能继续使用API函数呢?答案当然是Of Course! 其实仔细看两者并没有多大的区别,先看看在vb.net中如何调用: 首先添加一个类模块,来封装此API函数: <span style="font-size:14px;"> Public Declare Function SetParent Lib "<span style="color:

Vb.net/VB 声明API函数实现父窗口功能

回想第一次敲机房收费.自己调用了api函数实现了父窗口及其子窗口最小化的功能.现在再次遇到,自己就在思考,能不能继续使用API函数呢?答案当然是Of Course! 事实上细致看两者并没有多大的差别.先看看在vb.net中怎样调用: 首先加入一个类模块,来封装此API函数: <span style="font-size:14px;"> Public Declare Function SetParent Lib "<span style="color

UCOS-III API函数

附录:UCOS-III API函数 任务管理 就绪列表 挂起队列 时间管理 信号量 消息队列 内存管理

使用windows API函数获取目录下所有文件名---目录下文件的扫描和处理

直接上代码 // test_max.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <windows.h> #include <Shlwapi.h> #include <iostream> #include <string> #include <vector> #pragma comment(lib,"shlwapi.lib") //注意放置的位置

linux API函数大全

还没有认真研读过,今晚在其他博客上找了比较久,今晚时间也不多了,等有空再细看 先复制先 获取当前执行路径:getcwd 1. API之网络函数 WNetAddConnection 创建同一个网络资源的永久性连接  WNetAddConnection2 创建同一个网络资源的连接  WNetAddConnection3 创建同一个网络资源的连接  WNetCancelConnection 结束一个网络连接  WNetCancelConnection2 结束一个网络连接  WNetCloseEnum

如何通过HOOK改变windows的API函数(找到函数的相对偏移)

我们知道,系统函数都是以DLL封装起来的,应用程序应用到系统函数时,应首先把该DLL加载到当前的进程空间中,调用的系统函数的入口地址,可以通过GetProcAddress函数进行获取.当系统函数进行调用的时候,首先把所必要的信息保存下来(包括参数和返回地址,等一些别的信息),然后就跳转到函数的入口地址,继续执行.其实函数地址,就是系统函数“可执行代码”的开始地址.那么怎么才能让函数首先执行我们的函数呢?呵呵,应该明白了吧,把开始的那段可执行代码替换为我们自己定制的一小段可执行代码,这样系统函数调