lua5.2 tips

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)
end

sample2:
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> end

is 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>
  end
end


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.sqrt
local io = io

---将_env编为nil,好处是即使错误编写也不会玷污全局空间
_ENV = nil
<定义库部分>


--将导出函数归纳到一个表中

return {
new = new
add = 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值