库和工具
相比Java、Python、Perl,Lua的开源工具和库可能并不算多,但其中不乏优秀之作。以下介绍的资源均可在http://lua-users.org/wiki/LuaAddons上找到,而且绝大多数都遵循着与Lua相同的许可协议。
一、Kepler
Kepler是一个简单且轻量的Web开发平台(但这并不意味着只能用它来开发简单的应用),支持用Lua撰写Web程序,因此相当易学易用,并且能较方便地应用在一些资源受限的系统中。由于使用ANSI C和Lua进行开发,所以它能移植到任何支持ANSI C的平台上。
Kepler由多个Lua扩展库组成,包括CGILua、LuaSocket、LuaFileSystem、Copas、LuaSQL、LuaLDAP、LuaExpat、LuaXMLRPC、LuaSOAP、LuaZip、Xavante等,它们可大致分为核心库和功能支撑库两部分。其中核心是CGILua和LuaSocket,后者负责TCP/UDP sockets的操作,前者则可以创建动态页面并处理web表单上的输入数据。Kepler通过CGILua起动器(launcher)使得Web服务器能执行CGILua和Web程序并与之通信。目前的版本已经包括适合CGI、FastCGI、Apache、IIS、Tomcat、Zope的CGILua起动器,因此用Lua开发的Web程序可以在这些种类的服务器中自由迁移,只要同时安装上对应的CGILua起动器。
LuaFileSystem是对标准Lua库中文件读写功能的补充,它提供了一种可移植的方法来访问系统的目录结构和文件属性。Copas则是一个基于协程的服务调度器。Xavante是一个用Lua开发的支持HTTP 1.1的Web服务器,它直接支持CGILua而无需起动器。
其它的组件提供了SQL数据库访问、XML解析、LDAP、SOAP、XMLRPC、ZIP文件操作等功能,用户如果只需要其中的某些功能,可以抽出相关组件(及其所依赖的组件)来使用。
二、wxLua
GUI是开发人员花费气力比较大的一个领域,因此简化GUI程序的编写一直是广大程序员的努力方向。随着脚本语言的兴起,将动态、灵活、易用的脚本语言引入到GUI开发中是一种非常有价值的尝试。由于复杂的GUI布局需要大量的描述信息,所以比起其它脚本来,既适合编程又适合描述数据的Lua语言在构建GUI上就具有独特的优势。
wxWidgets是一个著名的跨平台C++ GUI库,wxLua在Lua与wxWidgets之间架起了一座桥梁,通过它Lua代码几乎可以调用wxWidgets的所有功能。wxLua基本将wxWidgets的类体系映射到了Lua(基于原型)的对象模型中,这使得程序员能以基于对象或面向对象的风格来开发wxLua程序。一个Lua脚本的撰写、运行、测试和修改可以非常快速,这无疑大大提高了GUI程序的开发效率,因此wxLua非常适合快速原型的构造。另外,Lua本身以及wxWidgets良好的可移植性使得相应的Lua GUI程序在许多平台上都能顺畅地运行。
三、Pluto
虽然Lua中的表能通过表构造器以Lua代码的形式保存到文件中从而实现持久化,但当数据之间有着复杂的引用关系,并且存在循环引用、共享引用等特殊情况时,这个任务就变得相当困难与繁琐了。Pluto持久化库能够为用户解决这个难题。在它的帮助下程序员可以将任意复杂的表数据保存到特殊格式的二进制文件中以待将来恢复,库会自动处理循环引用之类的情况。
除表之外,Pluto还支持函数(确切地说是闭包)、thread的持久化,这种能力非常有意义。大家都知道程序调试中的一个基本动作就是复现bug,但很多时候bug产生的条件是非常复杂的,依赖很多因素,开发者很难精确地构建出完全一致的运行环境。而利用Pluto对函数和thread的持久化能力,我们可以把bug发生时程序的完整运行环境保存下来,今后就可凭此方便地复现bug。另外一个重要应用是游戏进度的保存。实现游戏逻辑的Lua脚本的运行状态能随时写入到文件中留待将来恢复,这使得在任何时间点保存游戏成了一件非常容易的事情。
四、LuaCOM
LuaCOM是一个支持Lua与符合COM规范的组件对象(确切一点说是自动化对象)进行交互的扩展库。所谓交互包括了两个方面,首先是允许Lua程序使用COM对象。LuaCOM支持注册在系统注册表中的COM对象的动态实例化,也支持动态访问运行中的对象。在LuaCOM的帮助下,调用COM对象方法就象调用普通Lua函数一样,存取属性也与存取表的字段类似,同时它还负责Automation数据类型与Lua数据类型的自动转换。有了这些特性,Lua程序操作COM对象就变得容易多了,再加上Lua天生的动态性,这无疑使其成了一门非常灵活的组件装配语言。
交互的另外一个方面就是支持用Lua来实现(自动化)组件对象并提供给外部客户使用。LuaCOM同时支持进程内和进程外组件,它提供了一些辅助函数来处理注册、对象实例化这类事情,从而简化了相关工作。由于LuaCOM实际上是根据Lua的表来构造一个COM对象,所以我们可以做一些非常有趣的事情:在userdata数据类型(代表不属于Lua世界的数据结构)和动态元机制的支持下,Lua能通过表访问各种各样的外部数据,包括C++对象、C结构或者CORBA对象等等;LuaCOM可以很方便地将代表这些数据的表包装成一个COM对象给外部使用,从而使得那些老迈的应用程序和库无需太多的努力便能跻身于COM世界。
五、tolua
直接用C实现某些功能,然后将相应的函数导入到Lua中是很常见的做法。不过尽管Lua提供了与C语言交互的API,但用户必需手工进行繁琐的Lua栈(用于与C交换数据)操作,而且还需注意两种语言数据类型的正确转换。难怪有人说使用Lua的C API就象在使用汇编语言一样。为了减轻程序员的负担,一些C/C++ Wrapper应运而生。
tolua本身不是一个Wrapper,但它是一个Wrapper代码自动生成器。它使用一种称为包(package)的文件来描述要导入到Lua环境中的常量、变量、函数、类和方法,这种文件按照简化了的C++头文件格式编写。使用时首先让tolua解析包文件以生成含有相应胶水代码的C/C++源文件。然后将生成的源文件编译并与那些具体实现功能的目标模块链接起来。
tolua虽然自动产生胶水代码,但需另外撰写描述文件,所以仍然不够方便。其它一些Wrapper库则利用C++模板元编程技术来自动生成合适的连接代码,从而避免了额外的描述文件,比如使用boost库的luabind。
六、LuaJIT
Lua非常高效,它运行得比许多其它脚本(如Perl、Python、Ruby)都快,这点在第三方的独立测评中得到了证实。尽管如此,仍然会有人不满足,他们总觉得“嗯,还不够快!”。LuaJIT就是一个为了再榨出一点速度的尝试,它利用JIT编译技术把Lua代码编译成本地机器码后交由CPU直接执行。LuaJIT测评报告表明,在浮点运算、循环和协程的切换等方面它的加速效果比较显著,但如果程序大量依赖C编写的函数,那么运行速度便不会有什么改进。目前LuaJIT只支持X86 CPU。
LuaJIT中包括一个名为Coco的库,用户可以单独使用它。Coco为C函数提供了真正的协程能力,用户能在C函数内部的任何一点将协程挂起,然后在将来用协程恢复操作返回到那一点。在标准Lua中,协程的挂起与恢复是不允许跨越C函数调用边界的。Coco使用了一些依赖于特定系统的特性,因此在移植程序时要特别注意。
七、ChunkSpy
Lua的虚拟机字节码指令集并非语言定义的一部分,因此官方没有提供相应的文档。用户当然可以通过查看相关源代码来获取信息,但这毕竟不方便。
ChunkSpy是一个Lua虚拟机字节码反汇编器,可以将一个二进制Lua代码块输出为非常易读的各种格式(详细或简略,带或不带源程序)的字节码汇编文件。而且它还支持交互式的反汇编,用户在敲入一行代码后立刻就能看到对应的字节码指令。ChunkSpy的作者写过一篇详细的介绍Lua5虚拟机指令的文章,名为《A No-Frills Introduction to Lua 5 VM Instructions》,你在项目主页上能找到它。这篇文章现在已经针对最新的Lua5.1做了更正。另外,他还是Yueliang项目的开发者,这个项目采用Lua语言本身来实现Lua。从项目名来看,作者应该是个华人。
八、其它
另外一些库与工具还包括LuaEDIT、LuaEclipse、VS’05LuaLangPack(它们都是IDE或IDE插件),LuaWrapper、CaLua、CPB、CppLua(Wrapper库),LuaProfiler(性能测量工具)等,读者可以在lua-user.org与luaforge.net网站上找到它们以及其它有用资源