All Stories

继续Lua

  又看了一会儿PIL,以及云风blog上的一些文字,以及Lua Manual等等,终于有点眉目了。  完全可以下放权力给Lua,让它来创建wxScintilla对象,然后通过某些方法,把这个对象返回给C++,在C++看来,就是一个lua_touserdata吧。  至于如何保存和索引这个userdata,从PIL中看到,可以保存到registry中,也可以在registry中再多加一层索引,放个weak table。而索引方式,可以用一个C++指针,在Lua看来是lightuserdata,作为索引的最好方式之一,不过我还没想明白,到底怎么转化为实际生产力。倒是看清楚了些registry的操作方式,就是一个表,只不过该表在Lua栈中的索引是固定的值。还看清楚了些weak table的工作方式,weak table,也许叫weak hash或weak map更能让习惯用C++的人明白些,里面的每一条记录,都是一对key和value,而这个weak table可以将它的key,或者value,或者两个都是设置成weak的。weak的意思是说,假设我这个值(key,或value,到底是哪个,要看这table的属性,把metatable中的__mode域设成\"k\"或\"v\")已经没人用了,就把这条记录在垃圾回收时都删掉。原来就是这么一回事,PIL中说,应用lightuserdata时,要结合weak table来用才好,并一笔带过举了个窗口消息处理的例子,我没看明白,晕!其实,我想我是知道作者的意图,我在Lua中创建了userdata,一方面要能方便地供C++和Lua两边都能使用,另一方面,要防止Lua自作主张地把userdata回收掉。用weak table大概就是为了能让程序员来控制userdata销毁的时机吧。

看PIL一脸茫然

  今天没干什么事,看PIL去了,结果一脸茫然。昨天兴奋地以为用luabind就能把那些问题都解决了,实际上高兴得早了点,而且我也想偷懒到极致,用SWIG生成胶水代码后,再在C++和Lua中进行无差别地使用对象。我现在的应用场景是,在C++中创建了对象,如何在需要的时候,调用Lua脚本的某个函数时,在那函数中能方便地访问到那个对象进行操作。看LuaTinker是可以把C++对象直接映射到Lua脚本的某个全局变量中去,不过我感觉使用全局变量不太好,而且是C++在主动做事。我希望的是这样一种形式,C++在调用Lua函数时,把该对象的指针作为参数传递过去,Lua函数能根据这个参数取得实际的对象,进行操作。在网上又看了些文章,感觉这应该是一种很常用的用法才对,也不知道别人是怎么用的。  初步的想法是C++创建对象时,用lua的newuserdata来分配空间,在这空间内进行创建。然后有了个地址,即指针,把这对指针和数据保存起来,可能用得到设施有registry和weak table,还有lightuserdata这种东西,但具体怎么用,还没搞明白。看PIL云里雾里,还是得写些代码实验一下。

新版luabind

  今天偶然看了一下luabind的官方网站,发现1月4日时有0.8版出来了,让我有点惊喜,想想上个版本0.7,是2006年1月时放出的,沉寂了20个月,2008年10月才有0.7.1。中间这漫长的近两年时间,让我都以为这个项目太监了呢。  兴匆匆地把代码下载下来。印象中,网上有人说过luabind不需要事先编译,直接把源代码加入到工程中一起编译就能用。不过我这次还是想试试把它编译成单独一个库。看到0.8只有一个Jamroot,设置好LUA_PATH和BOOST_ROOT,把bjam.exe复制过来试了几次,说找不到什么文件或者目标,晕,对bjam可是一点都不了解,也不知道从何下手。从网上看到有人说luabind只能用VC7编译,我诧异了,还是想试试MinGW的编译。直接自己输命令行g++来编译,只要设置好lua和boost的包含路径,是可以编译的,每一个.cpp文件都能编译通过。最后从0.7里提取出makefile来,这个makefile也有点问题,编译命令行参数要改一下,主要是包含路径,然后就可以用MinGW编译生成一个libluabind.a了。  这下好了,苦恼了很久的怎么让Lua脚本使用C++对象的问题应该很容易解决了。至于MDI中多个视图的问题,简单点,就每次都把当前激活窗口的视图指针传给脚本,稍微麻烦一点的,用C++写个方法来获取想要的视图指针,返回给脚本使用。昨天研究了wxScintilla.h文件,直接用SWIG就可以生成一堆胶水代码,不过还没有试过能不能正常使用,想来应该没什么问题,对SWIG的好感不是一天两天了,哈哈。

编译Xerces-C++和wxLua

  因为考虑到要跨平台,所以不能用MSXML了,而且对于MinGW能不能直接使用MSXML我都不抱希望,于是在几个开源的可跨平台的XML解析器中进行选择,并且只能是用于C/C++的。候选项包括expat、TinyXML、libxml/libxml++、Xerces-C++。我不喜欢expat的实现方式,也不习惯TinyXML的只有DOM的解析方式,而libxml/libxml++则是因为捣腾了一阵子还是没能用MinGW正确编译,最后的选择只剩下Xerces-C++。而实际上编译Xerces-C++也花了我一些时间。网站上最新的是3.0.0,倒是有VC7、VC8、VC9的编译好的包,不过我要MinGW的,所以下载下来源代码,看了一下网站上的说明,先装好msys,选好参数运行./configrue,就会生成makefile。而这生成的makefile似乎并不能直接用MinGW的make过,需要稍微修改下,也就是把其中所有的什么dirstamp目录的创建和依赖都删掉,方能编译。  编译wxLua稍微好过一点,不过一开始绕了点远路。从CVS下下来的源代码,到build/msw下找makefile.gcc文件,这个文件少了写了两个编译选项,以致于在生成库时在链接时总是去找WinMain,开始不明所以,硬是把LDFLAGS设为-shared,在编译库时是没问题了,但编译出来的.exe文件就不行了。后来发现只要添加LINK_DLL_FLAGS := -shared和LINK_MODULE_FLAGS := -shared就可以一切正常了。当然wxLua依赖于wxWidgets,所以事先要设置好WXWIN和WXCFG环境变量,而且最后面不能有反斜杠。只要设好了这两个环境变量,用VC9倒是可以很顺利地编译过。  有些时候不免要抱怨一下,开源的东西,易用性可能确实差了点。

同事要走

  今天旁边的同事突然问我有没有空一起去吃饭,本来还以为算是几个同事的年终聚餐,结果到了餐桌上才知道,原来他马上要离职了,就在这三四天里会办完手续。  这样自发地跟项目组里的同事出来吃饭,我还是第一次。我真是个很奇怪的人,当年在测试组时,第一年,也是不跟测试组的人一起活动,直到后来搬了家,才开始慢慢和他们一起玩。发现自己其实很势利啊。  今天喝了一点啤酒,话也多起来了。平常跟同事说的话也不多,而且脾气也挺坏的。说了很多公司的事,有点惆怅,也许跟我这几天心情本就不好有关吧。  人来人往,没有终点。

嵌入Lua即可

  今天又看了一下wxLua,其实很简单一回事只要把用CVS下载来的wxLua源代码编译一下,生成一个wx.dll文件(当然是在Windows平台下的),该文件依赖于wxMSW的两个dll,分别是wxmsw28u.dll和wxmsw28u_stc.dll,如果用不同的编译器,或者编译选项,可能会有不同的文件名后缀(注,不是扩展名)。我是用MinGW最新扩展4.3.2 TDM-2来编译的,把编译出来的dll放到搜索路径下,用lua.exe就可以直接运行wxLua自带的几个例子程序了,比如auidemo.wx.lua。  开始时,还在想到底是嵌入一个纯粹的Lua解释器,还是嵌入wxLua。其中的区别就是嵌入wxLua可能会需要多点C/C++代码加到工程中,作为胶水代码连接lua代码和wxWidgets。现在发现,其实不用管这么多了,只要嵌入一个纯粹的Lua解释器就够了,再设定好搜索路径,即package.cpath,就可以自由地装载wxLua了,其他的第三方库也可以用了,比如LuaXML、LuaZip等等。  我仰天长笑,接下来的问题是,如何让外部的Lua脚本识别出各个scintilla控件。MDI界面必定会有多个Scintilla视图,怎么能让脚本方便自主地获取到自己需要操作的那个视图呢?

2号了

  不知不觉,2008已经过去,又是一事无成的一年,凄凉到我有点不堪回首。  12月31日是江江的生日,江江居然邀请我到她家去吃火锅,这让我有点受宠若惊。记得30日时她发邮件,我还没反应过来,一直到31日上午才明白,于是思量着送点什么小玩意儿意思一下。一直到下午快下班的时候才跑到孙同学那里去,抢了她放在机箱上的娃娃。说受宠若惊,不是夸张,而是有原因的。一是我自以为跟江江并不那么熟络,二是我知道江江有BF但她却一直吞吞吐吐,这么邀我去,不就让我什么都知道了吗。不过太多的猜测,或者说心里搞得太明白,反而会让生活变得累人,所以还是不管那么多了。到了江江家,是一套七八十平的两室两厅,有点温馨的感觉。江江的BF似乎有点眼熟,可能是以前哪里见过,但我一点都记不起来,但是他说见过我,汗!火锅味道不错,还有很多肉和丸子,是我很喜欢吃的东西。吃过火锅又打麻将,一直到午夜12点,真是心旷神怡啊!没想到这次新年钟声响起时,我是在打麻将,哈哈。以前的各次印象已经差不多全没了,只记得有一年,大三吧,居然是在自习,欢呼声传出时,我刚刚走出二教大门。  1号,也就是昨天,在家宅了一天,连饭也没正常吃。先是捣鼓了一阵wxLua,它的出现让我犹豫,我是只嵌入Lua,还是嵌入wxLua呢。用嵌入wxLua的好处是,除了用脚本来表达业务逻辑外,界面的一部分也可以方便地用脚本来做了。但从网上看到的一些文章看来,wxLua的评价并不高,而且最大的问题可能是绝大部分开源软件都有的问题,技术支持太少,出了问题不知从何下手寻找解决方案。从CVS下载下来最新代码,直接用MinGW编译还不过,要改下makefile才行,而用vc9编译,则完全不知道如何下手修正了。然后出去吃了个KFC,修剪了一下头发,就看小说去了,看到后半夜!  2号了,好些天前就跟猫猫约好去看电影,起床玩了一会儿电脑,掐着时间出去坐335,到中信广场。来深圳这么久,看电影只去过1次CocoPark的百老江,去过3次东海太平洋。这次不知猫猫从哪里弄来的电影票,刚好去看看新南国的环境怎么样。先去吃了顿泰国菜,然后晃悠上去。片子还是不错的,冯小刚作品,葛优,舒淇主演《非诚勿扰》,有点搞笑,中间有点悲伤和无奈。看完电影,去购书中心晃了一个多小时,跑去喝鸭血汤作为晚饭,然后打道回府!  ……

MSXML删除节点

  昨天遇到一个问题,用MSXML操作XML时,删除一个子节点,可是死活删不掉。后来想到一个变通的办法,把这个子节点的标志性属性值改掉,这样其他处理过程就认不出这个节点了,就相当于删除了,很黄很暴力。  今天再去定位这个问题时,发现原来那子节点真的被删掉了。进一点试验发现,只要在删除该子节点前,先随便改一下这个子节点的一个属性值,下面的删除操作就正常了,但如果没有那个修改操作,就删不掉,真是怪事!  我当时还以为是不是因为子节点下面还有其他孙子节点,还想是不是要修改一下删除子节点的封装方法,递归地删除掉所有子孙节点呢!看来不必了!

e这么烂的程序也卖

  今天在公司看到一个同学在用e,有点好奇,早听闻它有“Windows下的TextMate”之称,以前也下载来装过,只看到界面很简单,功能也很简单,于是就没下文了。今天又有点兴趣,就让同事共享给我再试用一下。  还是老样子,界面上没什么改进,也许比之前我试用时功能上有所增强,但以我目前的眼光看来,它还是太简单了。总的说来,只有一个特色功能,就是bundles。不过可能TextMate赖以成名的就是bundles了,e就是全盘照抄了,从网上看到,说e的作者和TextMate的作者是老乡,两人协商过,让e可以直接使用TextMate的bundles。所有的人都说,e只有TextMate的一小部分功能,这我也是相信。但是最让人受不了的是,e运行极其不稳定,随便点几下就是挂起,或者崩溃。这么烂的程序居然也来卖,而且听同事说可能卖得还不错,我想这全沾了TextMate的光啊!因为说,它的一切思想,无论是从程序开发的角度,还是用户体验的角度讲,都是很好的,但这一切都是TextMate赐予的,e里唯一有点自己特色的是,用类似异步可插入协议的方式来修改配置。我没用过TextMate,不晓得它在这方面是怎么做的。  看了e后,另外一个同事就说,我们现在的Impeller应该也好卖吧,有语法结构树,有自动完成,有调试执行,我笑!