Lua有很多封装.其中的利弊已经有不少介绍.只是提一下luaplus.本来期望值蛮高的.但后来发现文档质量不高.sample编译不过去.不过调试功能做的比较强..
最后选择了LuaTinker.一个韩国人写的.2个文件.5个sample.简单清晰.赞一个.~
首先试验了几个基本功能.都没什么问题.
当时比较疑惑的几个问题是.在lua中可以使用指针么?可以使用c++中的数据结构么?.
lua中的函数可以以指针为参数么?
结论是可以的.不过跟强大的luabind比起来.luatinker没有对导出枚举提供支持.
但其他方面功能并不差.
比如c++中有类A
lua中定义
但如果以对象引用为参数的时候发现对象被复制了
..
这里的 ra没有像引用一样工作 .而是以值传递的方式进入的函数
这就奇怪了..于是开始读代码
代码就不贴了.不过很显然的是.在LuaTinker里有写一堆处理引用的偏特化.也就是表明应该是考虑过引用的.
那问题出在哪了呢..
LuaTinker里调用一个lua里的函数的call是这样定义的
这时会有编译错误.是说A的拷贝构造函数是私有的.也就是说自动推导出的T为
A.
跟调用 Fun( a )效果是一样的.
但显示指定参数
就没有问题
..
那么..在模板参数推导的时候.为什么引用类型会被转换成对象类型呢?..
翻阅了c++标准以及c++primer.原来在参数自动推导中.会进行类型的隐式转换
在决定模板参数类型前,编译器执行下列隐式类型转换:
左值变换
修饰字转换
派生类到基类的转换
于是..引用类型.被转换为了一个左值.进一步讲.自动推导的模板函数的参数必须是值传递.
关于转换细节.请参阅以上两本书.
嗯..看来我又踩到了c++的陷阱.以前一直没注意..写的代码可能也会有类似问题..
那是否可以做个改动以避免这个陷阱呢.首先想到的是将call函数以一个类模板封装起来.因为类模板是必须要指定类型的
像这样
然后实现中显示指定LuaTinker的call的参数类型.后来发现LuaTinker的call的实现中有个push函数.也有同样的问题
.
push的实现是
到lua2type这里就开始对引用做处理了.而且都是类模板.不会有自动推导上的错误
.
于是把
push(L, arg);
改为
push<T1>(L, arg);
试验.成功
但感觉不是很方便,因为这只完成了一个参数的函数的支持.类似的还要写支持2参数.3参数的..
LuaTinker里只写到3参数.不够就自己写吧..
于是想能不能写个类把参数封装一下.想起loki的Typelist概念很好.于是想能不能定义一个
Valuelist. 这样在使用的时候,只要保证模板参数T2也是一个ValueList类型的,就实现了递归定义可以保存任意数量的数据。同时和Typelist一样,也需要一个结束类型标志。因此定义下面的结构作为结束标志
:
然后函数的参数类型就为ValueList并为ValueList< class T1,null_type >写个特化版本就可以了
.
Typelist技术在C++ 设计新思维中有详细的介绍.就不多说了.
但这样定义起ValueList很麻烦..又不能写一个模板函数来帮助解决(因为一旦通过模板函数推导.又会牵扯到引用类型的问题)
于是又想.能不能写个引用的封装.这样这个封装了引用的对象被复制也无所谓
.
后来想想.如果把RefHolder传入lua并使用.那就要注册这个类的某个特化版本.也就是说.如果想对类A的引用进行封装.那就要注册RefHolder到lua里..而且为了支持重载操作符.肯定要做更多工作
..
后来看了下luabind.如果希望传入引用.是要用Boost.Ref包装一下..那又要做很多处理..
折腾了一番..最后发现.嗯..算了.我在写的时候注意点.代码里再加上些注释跟说明.以此来避免使用引用时出现bug.会简单些..
还有一次在使用lua_tinker::table的时候程序发生了异常.
lua_tinker::table_obj是用来操作lua中的表的类.维护了lua中堆栈的状态.
lua_tinker::table是对table_obj的一个封装.通过table可以对lua中的表进行访问和操作.发生异常后看了一下堆栈.发现是lua_tinker::table中的指向table_obj的指针出现了异常.
于是检查代码.发现table_obj维护了一个引用计数.当此计数为0时则被删除.而这个引用计数在构造函数里初始化的时候为0..当时觉得很奇怪..按照对智能指针的理解.引用计数应该初始化为1吧..后来发现在table构造的时候先new出table_obj对象.然后手动对此对象增加一个引用计数.这样也没什么问题..但仔细一看.table有三个构造函数.其中有一个只构造了table_obj对象但没有增加此对象的引用计数.
感觉很奇怪..也许是粗心写漏了吧..作者又是韩国人.没法发信交流..
先自己改了..此问题解决..
如果哪位仁兄对此有研究.希望多多交流
.~
参考资料: http://blog.csdn.net/taodm/archive/2003/05/18/15766.aspx
调用函数