lua5.2 tips

来源:互联网 发布:精仿rmb货到付款淘宝 编辑:程序博客网 时间:2024/05/29 07:05

1. liblua的 编译

lua脚本中的C module必须采用动态链接库的形式.

如果lua脚本再被c程序调用,c程序和CModule都必须动态链接lua库,

(如果采用静态链接的方式,会报multiple Lua VMs detected错误,认为启动了两个lua虚拟机)。

这样,就需要把lua编译成动态链接库。

2.特殊函数

lua5.1 之中有一个luaL_register,用于把luaL_Reg 数组中的所有函数注册到lua中。但在lua5.2中已经不支持这一函数了,

lua5.2的手册中建议使用luaL_setfuncs来替代luaL_register.

在5.1中经常会把一些C函数注册在LUA_GLOBALINDEX 全局table中。

e.g.

lua_pushstring(L, name)

lua_pushcfunction(L, func)

lua_settable(L, LUA_GLOBALSINDEX);

在5.2中已经移除了LUA_GLOBALSINDEX,去而带之的是注册表。

在5.1中lua_setglobal() 和 lua_getgloba() 都用是LUA_GLOBALINDEX 伪索引。

在5.2中上面两个函数都是使用的注册标中的LUA_RIDX_GLOBAS伪索引(索引注册表的全局环境)

LUA_RIDX_GLOBAS是LUA state 注册表中与定义的两个值之一。另一个是

LUA_RIDX_MAINTHREAD 索引的是lua state的主线程状态。


【lua_toXXX,luaL_checkXXX】都不会改变stack中的值,但是lua_tolstring会改变stack中的值(例如index对应的是number,这个函数调用会改变stack中的实际值)

所以在使用lua_next来遍历table表时,不能将luaL_tolstring应用在table key上,否则会引起table遍历的混乱

3.lua文件编译

可以预编译成bytecode,加快lua脚本的加载.

luac -o [编译后脚本名] [脚本名]

4.其它补足

a) table.x ,table["x"] 访问table变量的2种方式,效果一样。例如

M.print(1,2)M["print"](1,2)

如何定义个table中的方法,可以如下:

sample1:local t={}function t.print(a,b)print(a,b)endsample2:t.print = function (a,b)print(a,b)end


b) lua脚本中可以使用tostring(v),来将各种类型的变量转换成string,如果v对应的metatable中有__string方法,会将这个方法的结果返回

c) lua语言中的for语句 可以解释成如下模型

for var_1,...,var_n in <explist> do <block> endis equivalent to the following code:do  local _f,_s,_var = <explist>  while true do     local var_1,...,var_n = _f(_s,_var)     _var = var_1     if _var == nil then break end    <block>  endend

for语法会帮助存储一些变量,所以尽量应该使用stateless iterator,这样可以减少内存消耗。for提供的机制无法满足iterator时,尽量使用closure来封装更多的数据(状态),

实在不行的情况下,用上面的_s(非变量),来存储更多的状态信息.因为closure的存取被table.field快。

d)lua脚本中的require可以保证module只被load一次。已经被loaded的module,它的返回值被存在package.loaded.<modname>

   require "modname"  被调用,并且找到对应的库文件时,lua会将 modname和找到的库文件的位置传给对应的库文件。

   关于require的执行流程

  • 首先判断是否已经在package.loaded的表中
  • 不在的情况下,依次遍历package.searchers list,如果整个search list中都没有找到合适的,会raise error
  • searcher list中包含preload,lua searcher,c searcher,c supper searcher
  • 例如lua searcher,就会利用传入的modname,以及lua path template,来查找对应的lua文件

关于这里的path template做简单说明:

编译的时候,lua runtime中会有个default path(?; ?.lua; /usr/local/lua/?/?.lua),这个可以作为运行时的path template

查找的时候,会用modname替换上面的?,依次查找各个路径是否有该文件。

对应lua ,c path template,会在启动时候查找环境变量LUA_PATH_5_2 ,LUA_PATH,LUA_CPATH_5_2,LUA_CPATH中的以双分号(;;)

标志的变量作为path template的开头搜索部分。


submodules,package

如果require的modname中包含点号,lua会将它变更成路径分割符,来查找该文件。

例如 path template:./?.luar;/usr/local/lua/?.lua当我们 require "a.b"时,实际查找的是./a/b.lua/usr/local/lua/a/b.lua/usr/local/lua/a/b/init.lua

我们在写一般的lua module时,可以按照下面的格式

--import section--导入库中要使用的全局函数或者外部函数,--使用local变量还有一个好处是速度比较快local sqrt = math.sqrtlocal io = io---将_env编为nil,好处是即使错误编写也不会玷污全局空间_ENV = nil<定义库部分>--将导出函数归纳到一个表中return {new = newadd = add}

补足:

在有些情况下,我们不能直接修改c binary so文件,但是它和其它c binary so重名了,怎么办?

有个小技巧

正常情况下,我们 require "mod"时,查找到该c library后会调用它的导出函数luaopen_mod,

但是可以通过短横线(-),来修饰c library name,但是调用的导出函数,却是忽略(-)之前的字符,例如

require "v-mod",同样查找的也是luaopen_mod

e) debug机能

lua提供的debug机能分为2类,一为检查类function,二为hooks function

可以通过 debug.getinfo(n),来获取当前活动栈中的信息,需要注意的是,调用debug.getinfo的函数A stack level 为 1(n=1),调用函数A的函数,level =2.

debug.getinfo:可以查找当前栈或者函数的相关信息

debug.getupvalue:可以查找closure的相关信息

coroutine抛出error的时候,并不会释放它的调用stack,所以这个时候你还是可以使用debug函数来检查一些变量

hooks可以监视function call,line code excuting,return call,count 

一些对性能有要求的测试,有可能的情况下,尽可能使用c interface

f) lua eclipse插件

Eclipse Update: http://download.eclipse.org/koneki/updates-nightly/ldt

如何安装:http://help.eclipse.org/luna/index.jsp?topic=/org.eclipse.platform.doc.user/tasks/tasks-127.htm

h) 如何在editor中表达一个长字符串,可以分行

  char lua_code[] = "                                     \                   function lprofT_mesure_function()    \                   local i                              \                                                        \                      local t = function()              \                      end                               \                                                        \                      i = 1                             \                      while (i < 100000) do             \                         t()                            \                         i = i + 1                      \                      end                               \                   end                                  \                                                        \                   lprofT_mesure_function()             \                   lprofT_mesure_function = nil         \                 ";




资源

lua library&tool

lua manual中文版

0 0
原创粉丝点击