Chinaunix首页 | 论坛 | 博客
  • 博客访问: 334294
  • 博文数量: 214
  • 博客积分: 4258
  • 博客等级: 上校
  • 技术积分: 2021
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-02 09:16
个人简介

http://blog.csdn.net/ly21st http://ly21st.blog.chinaunix.net

文章分类

全部博文(214)

文章存档

2018年(16)

2015年(1)

2014年(2)

2012年(22)

2011年(173)

分类: Python/Ruby

2012-09-19 10:20:07

lua 扩展库函数
 
01 int luaopen_libname(lua_State *L)  
 
03     static const luaL_Reg funcs[] =
04     {  
05         {"func1", func1},  
06         {"func2", func2},  
07         {NULL, NULL}  
08     };  
09   
10 #ifdef lua5.1  
11     //5.1 下直接使用luaL_register  
12     luaL_register(L, "libname", funcs);  
13 #else //lua5.2 
14     luaL_newlib (L, R);
15    
16     //或者
17     //lua_newtable(L);
18     //luaL_setfuncs(L, funcs, 0);
19     
20     //在lua脚本中只能这样使用 local clib = require "libname". 这样就不会污染全局环境或者
21  #endif  
22     return 1;  //返回table
23 }

 

***********************************************************************

***********************************************************************

1. luaL_register 2 luaL_setfuncs

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

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

使用如下。


1.2.int luaopen_libname(lua_State *L) 
3.4.{ 
5.    static const luaL_Reg funcs[] = { 
2.    {"func1", func1}, 
2.        {"func2", func2},  3.    {NULL, NULL} 
4.    }; 
5.#ifdef lua5.1   6.//5.1 下直接使用luaL_register 就好   7.    luaL_register(L, "libname", funcs);  8.#else //lua5.2   9.    lua_newtable(L);  
10.    //先把一个table压入VS,然后在调用luaL_setfuncs就会把所以的func存到table中   11.    //注意不像luaL_register这个table是个无名table,可以在的使用只用一个变量来存入这个table。   12.    //e.g local clib = require "libname". 这样就不会污染全局环境。比luaL_register更好。   13.    luaL_setfuncs(L, funcs, 0); 
14.#endif   15.    return 1;  //返回table   16.  
17.} 
 


luaL_register, 和 luaL_setfunc 实现很想,这不过luaL_register会先创建一个全局table在把函数注册到这个table中。

具体实现请参考lua源马。


本篇文章来源于 Linux公社网站()  原文链接:

 

-------------------------------------------------------------------------------

-------------------------------------------------------------------------------

? 正式招聘 web 平台开发工程师 | 返回首页

Lua 5.2 的细节改变

最近想试一下, Lua JIT 2.0 能给我们的系统带来多大的提升。但可惜的是,我们一开始就在用 Lua 5.2 来构建系统,而 Lua JIT 2.0 只支持 Lua 5.1 的 API ,在可以看到的时间里,恐怕也不太会去支持 5.2 了。

所以,我只能想办法反向支持 Lua 5.1 。

语法层面最重大的改变是 Lua 5.2 取消了环境表这个概念,转而提供 _ENV 这个语法糖。

许多小细节是 C API 上的变化。这使得按 Lua 5.2 标准写的 C 库,无法在 Lua 5.1 环境下编译。我打算用 Lua 5.1 的 API 来模拟出来。

我并没有完全实现所有 Lua 5.2 新增的 API ,比如对 continuation function 的支持,几乎不可能在 Lua 5.1 已有的 API 上完成的。

一些简单的 API 的实现我

luaL_checkversion 很有用,但很难完全实现其功能。无法检测出重复链接。

lua_arith 虽然可以实现,但是直接用 5.1 的 API 模拟出来,会比较繁琐,性能低下。而我也没用它,所以就放弃了。

lua_upvalueid 和 lua_upvaluejoin 估计也不太会用的上。

luaL_Buffer 在 Lua 5.2 里结构变了,所以,新增加的 luaL_buffinitsize 和 luaL_prepbuffsize 是无法实现相同的语义的,不想改变 5.1 里的 auxlib 的行为,所以只能回避用它们了。

对于 lua 层面的 API ,改变最大的是 load 的语义。这是和 _ENV 一起改变的,完美支持会比较麻烦。我先

一开始,我想通过修改用户传入的代码,在前面增加一小段代码来模拟 _ENV 的行为。后来发现,我们自己用的库里有一部分是用 binary 格式来在 State 间传递 function 的。而二进制模式的代码,不能通过附加文本代码的方式来改变行为。这个难题下一步再去解决。

Lua 5.2 里的 string.format 中,%s 会默认调用对象的 __tostring 方法,而 5.1 则不会。我不打算更新 5.1 中的 format 方法,还是把 lua 代码中的 format 参数显式调用一下好了。那些地方多是用来输出 log 的,只要避免将 nil 传进入就可以了。

Lua 5.2 改进了 coroutine 的支持,好在 Lua JIT 2.0 也同样支持了。但是 Lua JIT 2 似乎对 __pairs 的支持(默认关闭)是有 bug 的。今天调试了很久终于确认并非我们自己代码的 bug 。

我构造了一个简单的 test case :

local tbl = {} local a = { values= { foo = 1 } } local iter = function(value) local function loop(t,k) return next(t,k) end return loop, value end local mt = { __pairs = function(self) local values = rawget(self, "values") return iter(values) end } setmetatable(a,mt) tbl.a = a local function trav(k,t) if type(t) == "table" then print(k, t) for k,v in pairs(t) do trav(k,v) end end end trav("",tbl)

在 luajit 2.0 下运行,会输出两个 a :

table: 0x00327fa8 a table: 0x00321d00 a table: 0x00321d00

a 这个字段被重复迭代了两次。

今天还发现,debug 库中的 getinfo 信息,lua 5.2 比 lua 5.1 更丰富。5.2 用 nparams 字段,可以取得函数的参数个数。而 5.1 里把参数和 local 变量一视同仁。

在旧代码里,我们试图这样去取得一个函数的参数名字(为了匹配通讯协议)。

local nparam = debug.getinfo(f,"u").nparams local p = {} for i=1,nparam do local name = debug.getlocal(f,i) table.insert(p, name) end

在 Lua 5.1 里,是没有 nparams 字段的。而且 getinfo 不能传入一个函数,而必须是一个堆栈层次数。我只好使用了一个变通的方案来达到相同的功能。

local function gen_hook(p) return function() local i = 1 while true do local name = debug.getlocal(2,i) if name == nil or string.byte(name) == 40 then -- '(' is 40 break end p[i] = name i = i + 1 end error() end end function debug.params(f) local p = {} local co local function probe() debug.sethook(co, gen_hook(p), "c") f() end co = coroutine.create(probe) coroutine.resume(co) return p end
Comments

还在用5.1.4。。不敢切换5.2,更别提jit了

lua5.1移植到luajit2的兼容性问题,有没有大大说说啊,用了luajit2有一次怪异的宕机,也没解决。

@ST 不晓得你说的LuaJIT2在生产环境不靠谱是指哪方面,从lua5.1移植到luajit2是有点儿兼容性问题必须解决,但是我们现在就是用于生产环境的。

@ST 听到这个消息,我感到万分悲痛。
@Cloud 为啥不直接用 5.1 呢

@zhouzuoji

Lua 5.2 的 _ENV 是去掉 5.1 的"环境"这个语言核心特性, 用一个语法糖来兼容.

这是在做减法.

上面想说的是弊大于利:)

云风一直在倒腾不同的语言工具不同的版本,感觉完全没有必要。选择最适合自己的一个稳定版本就行了。现在很多互联网服务器跑的还是古老的unix和linux发行版呢。引入太多语法糖比多写几行代码,显然利大于弊。

LuaJIT在生产环境感觉很不靠谱. 之前尝试把项目转到LuaJIT, 发现了几处崩溃. 尽力解决掉一部分, 但后来经过评估, 还是没敢上.

 

--------------------------------------------------------------------------

--------------------------------------------------------------------------

8.1 – Changes in the Language

·Environment的概念变化了。仅Lua函数具有environment。要设置Lua函数的environment,请使用变量_ENV,或者使用函数

C函数不再有environment。如果你希望在几个C函数之间共享状态,请使用upvalue作为一个共享表。(你可以使用打开一个C库,并在所有函数之间共享同一upvalue)。

为了操作userdata5.2中称为user value)的"environment",使用新的函数

·Lua标识符不能使用区域相关的字符(换言之,不能使用中文作为标识符了)

·若垃圾回收器已停止,那么做一步回收动作,或做一次完全回收动作,都不会重启垃圾回收器(换言之,你需要先显式的启动它)。

·弱表和弱键现在按短暂表(Ephemeron table)处理。

·tail return事件在debug hook中被移除了。替换的办法是,尾调用生成一个特殊的新事件,tail call,因此debugger能够知道不会有对应的返回事件。

·函数值之间的相等判定发生改变。现在,一个函数定义不一定创建一个新值,它可能重用以前的值——当旧值与新函数没有明显的不同的时候。

------------------------------------------------------------------------

------------------------------------------------------------------------

 

阅读(1666) | 评论(0) | 转发(0) |
0

上一篇:eclipse安装c++插件教程

下一篇:lua5.2 改动 .

给主人留下些什么吧!~~