热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

解析Lua5.1中关于API函数学习教程

Lua5.1中关于API函数学习教程是本文要介绍的内容,主要是来学习

Lua 5.1中关于API函数学习教程是本文要介绍的内容,主要是来学习API函数lua中的应用,具体内容来看本文详解。

  1. lua_State* luaL_newstate() 

Lua脚本的编译执行是相互独立的,在不同的线程上执行。通过luaL_newstate()函数可以申请一个虚拟机,返回指针类型 lua_State。今后其他所有Lua Api函数的调用都需要此指针作为第一参数,用来指定某个虚拟机。

  1. lua_State* L = luaL_newstate();  
  2. void  lua_close(lua_State *L) 

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

  1. lua_close(L);  
  2. lua_State* lua_newthread(lua_State *L)  
  3. int   lua_gettop(lua_State *L) 

取得栈的高度

  1. for (int i = 0; i < 10; ++i)  
  2.       lua_pushnumber(L, i);  
  3. printf("%d", lua_gettop(L));  
  4. --> 10  
  5. void  lua_settop(lua_State *L, int idx) 

设置栈的高度,如果之前的栈顶比新设置的更高,那么高出来的元素会被丢弃,反之压入nil来补足大小。

另外,Lua提供了一个宏,用来从栈中弹出n个元素:#define lua_pop(L, n) lua_settop(L, -(n)-1)将指定索引上值的副本压入栈

  1. for (int i = 1; i <= 3; ++i)  
  2.       lua_pushnumber(i);  
  3. 栈中元素:(从下往上) 1 2 3  
  4. lua_pushvalue(L, 2)  
  5. 栈中元素:(从下往上) 1 2 3 2  
  6. void  lua_remove(lua_State *L, int idx) 

删除指定索引上的元素,并将该位置之上的所有元素下移以补空缺

  1. for (int i = 1; i <= 3; ++i)  
  2.       lua_pushnumber(i);  
  3. 栈中元素:(从下往上) 1 2 3  
  4. lua_remove(L, 2)  
  5. 栈中元素:(从下往上) 1 3  
  6. void  lua_insert(lua_State *L, int idx) 

移指定位置上的所有元素以开辟一个空间槽的空间,然后将栈顶元素移到该位置

  1. for (int i = 1; i <= 5; ++i)  
  2.      lua_pushnumber(i);  
  3. 栈中元素:(从下往上) 1 2 3 4 5  
  4. lua_insert(L, 3)  
  5. 栈中元素:(从下往上) 1 2 5 4 3  
  6. void  lua_replace(lua_State *L, int idx) 

弹出栈顶的值,并将该值设置到指定索引上,但它不会移动任何东西

  1. for (int i = 1; i <= 5; ++i)  
  2.       lua_pushnumber(i);  
  3. 栈中元素:(从下往上) 1 2 3 4 5  
  4. lua_replace(L, 3)  
  5. 栈中元素:(从下往上) 1 2 5 4  
  6. int   lua_checkstack(lua_State *L, int sz) 

扩大栈的可用尺寸,栈的默认尺寸是20,此函数会确保堆栈上至少有 sz 个空位。如果不能把堆栈扩展到相应的尺寸,函数返回 false 。这个函数永远不会缩小堆栈;如果堆栈已经比需要的大了,那么就放在那里不会产生变化。

lua_checkstack(L, 100)

  1. void  lua_xmove(lua_State* from, lua_State* to, int n)  
  2.  
  3. //access functions (stack -> C)  
  4. int   lua_isnumber(lua_State *L, int idx)  
  5. int   lua_isstring(lua_State *L, int idx)  
  6. int   lua_iscfunction(lua_State *L, int idx)  
  7. int   lua_isuserdata(lua_State *L, int idx)  
  8.  
  9. int lua_isnil(lua_State *L, int idx);  
  10. int lua_isboolean(lua_State *L, int idx);  
  11. int lua_istable(lua_State *L, int idx);  
  12. int lua_isfunction(lua_State *L, int idx);  
  13. int lua_islightuserdata (lua_State *L, int idx); 

上面四个函数都有一个同样的原型int lua_is*(lua_State *L, int index),用来查询某值是否能转换成某个类型的值。对于任意数字,lua_isstring都返回真。

  1. lua_pushnumber(L, 994);  
  2. lua_pushstring(L, "hello,lua");  
  3. lua_isnumber(L, 1)-->true  
  4. lua_isnumber(L, 2)-->false  
  5. lua_isstring(L,1)-->true  
  6.  
  7. int   lua_type(lua_State *L, int idx) 

得到一个元素的类型,返回整型,返回值是如下列表之一:

  1. #define LUA_TNONE  (-1)  
  2.  
  3. #define LUA_TNIL  0  
  4. #define LUA_TBOOLEAN  1  
  5. #define LUA_TLIGHTUSERDATA 2  
  6. #define LUA_TNUMBER  3  
  7. #define LUA_TSTRING  4  
  8. #define LUA_TTABLE  5  
  9. #define LUA_TFUNCTION  6  
  10. #define LUA_TUSERDATA  7  
  11. #define LUA_TTHREAD  8  
  12. lua_pushnumber(L, 55);  
  13. lua_type(L, 1)-->LUA_TNUMBER  
  14. const char* lua_typename(lua_State *L, int tp) 

将一个类型编码转换成类型名

  1. lua_typename(L, 1)-->boolean  
  2. lua_typename(L, 3)-->number  
  3. int   lua_equal(lua_State *L, int idx1, int idx2) 

如果依照 Lua 中 == 操作符语义,索引 index1 和 index2 中的值相同的话,返回 1 。否则返回 0 。如果任何一个索引无效也会返回 0。

  1. lua_pushstring(L, "this");  
  2. lua_pushboolean(L, 1);  
  3. lua_pushboolean(L, 1);  
  4. lua_equal(L, -2, -3)  
  5. -->0  
  6. lua_equal(L, -1, -2)  
  7. -->1  
  8. lua_equal(L, -1, -10)  
  9. -->0  
  10.  
  11. int   lua_rawequal(lua_State *L, int idx1, int idx2)  
  12. int   lua_lessthan(lua_State *L, int idx1, int idx2)  
  13.  
  14. lua_Number lua_tonumber(lua_State *L, int idx)  
  15. lua_Integer lua_tointeger(lua_State *L, int idx)  
  16. int   lua_toboolean(lua_State *L, int idx)  
  17. const char* lua_tolstring(lua_State *L, int idx, size_t *len) 

以上四个函数都有一个原型lua_to*(lua_State *L, int idx),用于从栈中取一个值。如果指定的元素不具有正确的类型,调用这些函数也不会有问题,

在这种情况下,调用lua_toboolean,lua_tonumber,lua_tointeger会返回0,其它函数会返回NULL。通常不使用lua_is*函数,只需在调用它们之

后测试返回结果是否为NULL就可以了。

  1. lua_pushnumber(L, 100)  
  2. lua_tonumber(L, 1)-->100  
  3. lua_pushinteger(L, 200)  
  4. lua_tointeger(L, -1)-->200  
  5. lua_pushboolean(L, 0)  
  6. lua_toboolean(L, -1)-->false  
  7. lua_pushstring(L, "hello,lua")  
  8. lua_tolstring(L, -1, &len)-->hello,lua  

注:len是传出参数,表示字符串的长度,如果想忽略此参数,传入NULL

  1. size_t  lua_objlen(lua_State *L, int idx) 

返回值的长度,如果类型不正确,返回0

  1. lua_pushstring(L, "hello,lua")  
  2. lua_objlen(L, 1)-->9  
  3.  
  4. lua_CFunction lua_tocfunction(lua_State *L, int idx)  
  5. void*  lua_touserdata(lua_State *L, int idx)  
  6. lua_State* lua_tothread(lua_State *L, int idx)  
  7. const void* lua_topointer(lua_State *L, int idx)  
  8.  
  9. //push functions (C -> stack)  
  10. void  lua_pushnil(lua_State *L)  
  11. void  lua_pushnumber(lua_State *L, lua_Number n)  
  12. void  lua_pushinteger(lua_State *L, lua_Integer n)  
  13. void  lua_pushlstring(lua_State *L, const char* s, size_t l)  
  14. void  lua_pushstring(lua_State *L, const char *s)  
  15. const char* lua_pushvfstring(lua_State *L, const char *fmt, va_list argp)  
  16. const char* lua_pushfstring(lua_State *L, const char *fmt, ...)  
  17. void  lua_pushcclosure(lua_State *L, lua_CFunction fn, int n)  
  18. void  lua_pushboolean(lua_State *L, void *b)  
  19. void  lua_pushlightuserdata(lua_State *L, void *p)  
  20. int   lua_pushthread(lua_State *L)  
  21. void  lua_gettable(lua_State *L, int idx)  
  22. void  lua_getfield(lua_State *L, int idx, const char *k) 

把 t[k] 值压入堆栈,这里的 t 是指有效索引 index 指向的值。在 Lua 中,这个函数可能触发对应 "index" 事件的元方法

  1. void  lua_rawget(lua_State *L, int idx)  
  2. void  lua_rawgeti(lua_State *L, int idx, int n)  
  3.  
  4. void  lua_createtable(lua_State *L, int narr, int nrec) 

创建一个新的空 table 压入堆栈。这个新 table 将被预分配 narr 个元素的数组空间以及 nrec 个元素的非数组空间。当你明确知道表中需要多少个元素时,预分配就非常有用。如果你不知道,可以使用函数 lua_newtable。

举例暂缺

  1. void*  lua_newuserdata(lua_State *L, size_t sz)  
  2. int   lua_getmetatable(lua_State *L, int objindex)  
  3.  
  4. void  lua_getfenv(lua_State *L, int idx) 

把索引处值的环境表压入堆栈

  1. void  lua_settable(lua_State *L, int idx);  
  2. void  lua_setfield(lua_State *L, int idx, const char *k)  
  3. void  lua_rawset(lua_State *L, int idx)  
  4. void  lua_rawseti(lua_State *L, int idx, int n)  
  5. int   lua_setmetatable(lua_State *L, int objindex)  
  6. int   lua_setfenv(lua_State *L, int idx)  
  7.  
  8. //'load' and 'call' functions (load and run lua code)  
  9. void  lua_call(lua_State *L, int nargs, int nresults);  
  10. int   lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)  
  11.  
  12. int   lua_cpcall(lua_State *L, lua_CFunction func, void *ud) 

以保护模式调用 C 函数 func 。 func 只有能从堆栈上拿到一个参数,就是包含有 ud 的 light userdata。当有错误时, lua_cpcall 返回和 lua_pcall 相同的错误代码,并在栈顶留下错误对象;否则它返回零,并不会修改堆栈。所有从 func 内返回的值都会被扔掉。

举例暂缺

  1. int   lua_load(lua_State *L, lua_Reader reader, void *dt, const char *chunkname);  
  2.  
  3. int   lua_dump(lua_State *L, lua_Writer writer, void *data); 

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

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

这个函数不会把 Lua 返回弹出堆栈。

举例暂缺

  1. int   lua_yield(lua_State *L, int nresults)  
  2. int   lua_resume(lua_State *L, int narg)  
  3. int   lua_status(lua_State *L)  
  4. int   lua_gc(lua_State *L, int what, int data) 

控制垃圾收集器。 这个函数根据其参数 what 发起几种不同的任务:

  1.  * LUA_GCSTOP: 停止垃圾收集器。   
  2.  * LUA_GCRESTART: 重启垃圾收集器。   
  3.  * LUA_GCCOLLECT: 发起一次完整的垃圾收集循环。   
  4.  * LUA_GCCOUNT: 返回 Lua 使用的内存总量(以 K 字节为单位)。   
  5.  * LUA_GCCOUNTB: 返回当前内存使用量除以 1024 的余数。   
  6.  * LUA_GCSTEP: 发起一步增量垃圾收集。步数由 data 控制(越大的值意味着越多步),而其具体含义(具体数字表示了多少)并未标准化。
  7. 如果你想控制这个步数,必须实验性的测试 data 的值。如果这一步结束了一个垃圾收集周期,返回返回 1 。   
  8.  * LUA_GCSETPAUSE: 把 data/100 设置为 garbage-collector pause 的新值。函数返回以前的值。   
  9.  * LUA_GCSETSTEPMUL: 把 arg/100 设置成 step multiplier 。函数返回以前的值。  
  10. int   lua_error(lua_State *L) 

产生一个 Lua 错误。错误信息(实际上可以是任何类型的 Lua 值)必须被置入栈顶。这个函数会做一次长跳转,因此它不会再返回。(参见 luaL_error)。

  1. lua_pushstring(L, "one error");  
  2. lua_error(L);  
  3. printf("%s", "本行已经执行不到了");  
  4. int   lua_next(lua_State *L, int idx)  
  5. void  lua_concat(lua_State *L, int n) 

连接栈顶的 n 个值,然后将这些值出栈,并把结果放在栈顶。如果 n 为 1 ,结果就是一个字符串放在栈上(即,函数什么都不做);如果 n 为 0 ,结果是一个空串。 连接依照 Lua 中创建语义完成,如果尝试把两个不能连接的类型连接,程序会给出错误提示。

  1.  lua_pushstring(L, "this");  
  2.  lua_pushboolean(L, 1);  
  3.  lua_pushnumber(L, 9989);  
  4.  lua_pushnumber(L, 1111);  
  5.  lua_pushboolean(L, 0);  
  6.  lua_pushstring(L, "满天都是小星星");  
  7.  lua_pushnumber(L, 1986);  
  8.  lua_pushstring(L, "onebyone");  
  9. -->'this' 'true' '9989' '1111' 'false' '满天都是小星星' '1986' 'onebyone'  
  10. lua_concat(L, 3);  
  11. -->'this' 'true' '9989' '1111' 'false' '满天都是小星星1986onebyone'  
  12.  
  13. lua_Alloc lua_getallocf(lua_State *L, void **ud) 

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

  1. void  lua_setallocf(lua_State *L, lua_Alloc f, void *ud)  
  2.  
  3. //Functions to be called by the debuger in specific events  
  4. int   lua_getstack(lua_State *L, int level, lua_Debug *ar)  
  5. int   lua_getinfo(lua_State *L, const char *what, lua_Debug *ar)  
  6. const char* lua_getlocal(lua_State *L, const lua_Debug *ar, int n)  
  7. const char* lua_setlocal(lua_State *L, const lua_Debug *ar, int n)  
  8. const char* lua_getupvalue(lua_State *L, int funcindex, int n)  
  9. const char* lua_setupvalue(lua_State *L, int funcindex, int n)  
  10. int   lua_sethook(lua_State *L, lua_Hook func, int mask, int count);  
  11. lua_Hook lua_gethook(lua_State *L)  
  12. int   lua_gethookmask(lua_State *L)  
  13. int   lua_gethookcount(lua_State *L) 

小结:解析Lua 5.1中关于API函数学习教程的内容介绍完了希望通过本文的学习能对你有所帮助!


推荐阅读
  • Beetl是一款先进的Java模板引擎,以其丰富的功能、直观的语法、卓越的性能和易于维护的特点著称。它不仅适用于高响应需求的大型网站,也适合功能复杂的CMS管理系统,提供了一种全新的模板开发体验。 ... [详细]
  • 问题描述现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能;在实际开发过程中 ... [详细]
  • 深入理解:AJAX学习指南
    本文详细探讨了AJAX的基本概念、工作原理及其在现代Web开发中的应用,旨在为初学者提供全面的学习资料。 ... [详细]
  • 在现代Web开发中,HTML5 Canvas常用于图像处理和绘图任务。本文将详细介绍如何将Canvas中的图像导出并上传至服务器,适用于拼图、图片编辑等场景。 ... [详细]
  • RTThread线程间通信
    线程中通信在裸机编程中,经常会使用全局变量进行功能间的通信,如某些功能可能由于一些操作而改变全局变量的值,另一个功能对此全局变量进行读取& ... [详细]
  • 洛谷 P4009 汽车加油行驶问题 解析
    探讨了经典算法题目——汽车加油行驶问题,通过网络流和费用流的视角,深入解析了该问题的解决方案。本文将详细阐述如何利用最短路径算法解决这一问题,并提供详细的代码实现。 ... [详细]
  • 近期尝试从www.hub.sciverse.com网站通过编程手段获取数据时遇到问题,起初尝试使用WebBrowser控件进行数据抓取,但发现使用GET方法翻页时,返回的HTML代码始终相同。进一步探究后了解到,该网站的数据是通过Ajax异步加载的,可通过HTTP查看详细的JSON响应。 ... [详细]
  • 问题场景用Java进行web开发过程当中,当遇到很多很多个字段的实体时,最苦恼的莫过于编辑字段的查看和修改界面,发现2个页面存在很多重复信息,能不能写一遍?有没有轮子用都不如自己造。解决方式笔者根据自 ... [详细]
  • spring boot使用jetty无法启动 ... [详细]
  • Web动态服务器Python基本实现
    Web动态服务器Python基本实现 ... [详细]
  • 理解浏览器历史记录(2)hashchange、pushState
    阅读目录1.hashchange2.pushState本文也是一篇基础文章。继上文之后,本打算去研究pushState,偶然在一些信息中发现了锚点变 ... [详细]
  • 本文探讨了如何通过Service Locator模式来简化和优化在B/S架构中的服务命名访问,特别是对于需要频繁访问的服务,如JNDI和XMLNS。该模式通过缓存机制减少了重复查找的成本,并提供了对多种服务的统一访问接口。 ... [详细]
  • 本文将从基础概念入手,详细探讨SpringMVC框架中DispatcherServlet如何通过HandlerMapping进行请求分发,以及其背后的源码实现细节。 ... [详细]
  • 协程作为一种并发设计模式,能有效简化Android平台上的异步代码处理。自Kotlin 1.3版本引入协程以来,这一特性基于其他语言的成熟理念,为开发者提供了新的工具,以增强应用的响应性和效率。 ... [详细]
  • 电商高并发解决方案详解
    本文以京东为例,详细探讨了电商中常见的高并发解决方案,包括多级缓存和Nginx限流技术,旨在帮助读者更好地理解和应用这些技术。 ... [详细]
author-avatar
huangyong黄勇_513
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有