注册

C++ 封装的 Lua 扩展库 fflua

在使用C++做服务器开发中,经常会使用到脚本技术,Lua是最优秀的嵌入式脚本之一。Lua的轻量、小巧、概念之简单,都使他变得越来越受欢迎。本人也使用过python做嵌入式脚本,二者各有特点,今天主要讲Lua相关的开发技术。Lua具有如下特点:
Lua 拥有虚拟机的概念,而其全部用标准C实现,不依赖任何库即可编译安装,更令人欣喜的是,整个Lua 的实现代码并不算多,可以直接继承到项目中,并且对项目的编译时间几乎没有什么影响
Lua的虚拟机是线程安全的,这里讲的线程安全级别指得是STL的线程安全级别,即一个lua虚拟机被一个线程访问是安全的,多个lua虚拟机被多个线程分别访问也是安全的,一个lua虚拟机被多个线程访问是不安全的。
Lua的概念非常少,数据结构只有table,这样当使用Lua作为项目的配置文件时,即使没有编程功底的策划也可以很快上手编写。
Lua没有原生的对象,没有cl**的关键字,这也保障了其概念简单,但是仍然是可以使用Lua面向对象编程的。
Lua尽管小巧,却支持比较先进的编程范式,lua 中的匿名函数和闭包会让代码写起来更加 优雅和高效,如果某人使用的C++ 编译器还比较老套,不支持C++11,那么可以尽快感受一下lua的匿名函数和闭包。
Lua是最高效的嵌入式脚本之一(如果不能说最的话,目前证据显示是最)。
Lua的垃圾回收也可以让C++程序收益匪浅,这也是C++结合脚本技术的重要优势之一。
Lua 的嵌入非常的容易,CAPI 相对比较简洁,而且文档清晰,当然Lua的Capi需要掌握Lua中独特的堆栈的概念,但仍然足够简单。
Lua的扩展也非常的容易,将C++是对象、函数导入到lua中会涉及到一些技巧,如果纯粹使用lua CAPI会稍显繁杂,幸运的是一些第三方库简化了这些**作,而FFLUA绝对是最好用的之一。
**嵌入Lua:**嵌入lua脚本,必须要把lua脚本载入lua虚拟机,lua中的概念称之为dofile,FFLUA中封装了dofile的**作,由于lua文件可能集中放在某个目录,FFLUA中也提供了设置lua脚本目录的接口:int add_package_path(const string& str_)
int load_file(const string& file_name_) throw (lua_exception_t)load_file就是执行dofile**作,若出错,则throw异常对象,可以使用exception引用目标对象使用what接口输出代码出错的traceback。当嵌入lua时,最简单的情况是把lua脚本当成配置使用,那么需要获取lua脚本中的变量和设置lua变量,FFLUA封装了两个接口用于此**作。lua是动态语言,变量可以被赋值为任何lua支持的类型,但C++是强类型的,所以两个接口都是范型的:template int get_global_variable(conststring& field_name_, T& ret_);
template int get_global_variable(constchar* field_name_, T& ret_);有时需要直接执行一些lua语句,lua中有dostring的概念,FFLUA中封装了单独的接口run_string:void run_string(constchar* str_) throw (lua_exception_t)嵌入lua时最一般的情况是调用lua中的函数,lua的函数比C++更灵活,可以支持任意多个参数,若未赋值,自动设置为nil,并且可以返回多个返回值。无论如何,从C++角度讲,当你嵌入lua调用lua函数时,你总希望lua的使用方式跟C++越像越好,你不希望繁复的处理调用函数的参数问题,比如C++数据转换成lua能处理的数据,即无趣又容易出错。正也正是FFLUA需要做到,封装调用lua函数的**作,把赋值参数,调用函数,接收返回值的细节做到透明,C++调用者就像调用普通的C++函数一样。使用FFLUA中调用lua函数使用call接口:void call(constchar* func_name_) throw (lua_exception_t)当调用出错时,异常信息记录了traceback。实际上,FFLUA重载了9个call函数,以来自动适配调用9个参数的lua函数。template RET call(const char* func_name_) throw (lua_exception_t);
......
template typename ARG5, typename ARG6, typename ARG7, typename ARG8, typename ARG9>
RET call(const char* func_name_, ARG1 arg1_, ARG2 arg2_, ARG3 arg3_,
ARG4 arg4_, ARG5 arg5_, ARG6 arg6_, ARG7 arg7_,
ARG8 arg8_, ARG9 arg9_) throw (lua_exception_t);

已邀请:

要回复问题请先登录注册