﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-iwangchuchu-随笔分类-游戏开发</title><link>http://www.cppblog.com/iwangchuchu/category/13595.html</link><description>海阔天空</description><language>zh-cn</language><lastBuildDate>Sun, 25 Apr 2010 12:02:05 GMT</lastBuildDate><pubDate>Sun, 25 Apr 2010 12:02:05 GMT</pubDate><ttl>60</ttl><item><title>[转]组件工厂 -----3D游戏开发</title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/23/113341.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Fri, 23 Apr 2010 08:06:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/23/113341.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113341.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/23/113341.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113341.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113341.html</trackback:ping><description><![CDATA[<div>狭义的游戏对象是指游戏世界中所能看到及可交互的对象，如玩家、怪物、物品等，我们这里也主要讨论这类对象在服务器上的组织及实现。</div>
<div>　　
<p>　　在大部分的MMOG中，游戏对象的类型都大同小异，主要有物品、生物、玩家等。比如在wow中，通过服务器发下来的GUID我们可以了解到，游戏中有9大类对象，包括物品(Item)、背包(Container)、生物(Unit)、玩家(Player)、游戏对象(GameObject)、动态对象(DynamicObject)、尸体(Corpse)等。</p>
<p>　　在mangos的实现中，对象使用类继承的方式，由Object基类定义游戏对象的公有接口及属性，包括GUID的生成及管理、构造及更新UpdateData数据的虚接口、设置及获取对象属性集的方法等。然后分出了两类派生对象，一是Item，另一是WorldObject。Item即物品对象，WorldObject顾名思义，为世界对象，即可添加到游戏世界场景中的对象，该对象类型定义了纯虚接口，也就是不可被实例化，主要是在Object对象的基础上又添加了坐标设置或获取的相关接口。</p>
<p>　　Item类型又派兵出了一类Bag对象，这是一种特殊的物品对象，其本身具有物品的所有属性及方法，但又可作为新的容器类型，并具有自己特有的属性和方法，所以实现上采用了派生。mangos在实现时对Bag的类型定义做了点小技巧，Item的类型为2，Bag的类型为6，这样在通过位的方式来表示类型时，Bag类型也就同时属于Item类型了。虽然只是很小的一个技巧，但在很多地方却带来了极大的便利。</p>
<p>　　从WorldObject派生出的类型就有好几种了，Unit、GameObject、DynamicObject和Corpse。Unit为所有生物类型的基类，同WorldObject一样，也不可被实例化。它定义了生物类型的公有属性，如种族、职业、性别、生命、魔法等，另外还提供了相关的一些操作接口。游戏中实际的生物对象类型为Creature，从Unit派生，另外还有一类派生对象Player为玩家对象。Player与Creature在实现上最大的区别是玩家的操作由客户端发来的消息驱动，而Creature的控制是由自己定义的AI对象来驱动，另外Player内部还包括了很多的逻辑系统实现。</p>
<p>　　另外还有两类特殊的Creature，Pet和Totem，其对象类型仍然还是生物类，只是实现上与会有些特殊的东西需要处理，所以在mangos中将其作为独立的派生类，只是实现上的一点处理。另外在GameObject中也实现有派生对象，最终的继承关系图比较简单，就不麻烦地去画图了。</p>
<p>　　从我所了解的早期游戏实现来看，大部分的游戏对象结构都是采用的类似这种方式。可能与早期对面向对象的理解有关，当面向对象的概念刚出来时，大家认为继承就是面向对象的全部，所以处处皆对象，处处皆继承。</p>
<p>　　类实现的是一种封装，虽然从云风那里出来的弃C++而转投C的声音可能会影响一部分人，但是，使用什么语言本身就是个人喜好及团队整体情况决定的。我们所要的也是最终的实现结果，至于中间的步骤，完全看个人。还是用云风的话说，这只是一种信仰问题，我依然采用我所熟悉的C++，下面的描述也是如此。</p>
<p>　　随着面向对象技术的深入，以及泛型等概念的相继提出，软件程序结构方面的趋势也有了很大改变。C++大师们常说的话中有一句是这样说的，尽是采用组合而不是继承。游戏对象的实现也有类似的转变，趋向于以组合的方式来实现游戏对象类型，也就是实现一个通用的entity类型，然后以脚本定义的方式组合出不同的实际游戏对象类型。</p>
<p>　　描述的有些抽象，具体实现下一篇来仔细探讨下。<br><br><br>在游戏编程精粹四有三篇文章讲到了实体以及实体管理的实现方案，其中一篇文章说到了实体管理系统的四大要素：定义实体怎样沟通的实体消息，实现一实体类代码和数据的实体代码，维护已经注册在案的实体类列表，和用来创建、管理、发送消息的实体管理器。</p>
<p>　　关于实体消息的内容之前讨论事件机制的时候做过一点说明，其实这也就是按接口调用和按消息驱动的区别，现在mangos的做法是完全的接口调用，所以引擎内部就没有任何的实体消息。实体代码实现和实体管理器是我们重点要讨论的内容。</p>
<p>　　另有一篇文章也提到了使用类继续的方式实现游戏对象的两大问题，一是它要求系统中的所有对象都必须从一个起点衍生而成，也就是说所有对象类在编译的时候已经确定，这可能是一个不受欢迎的限制，如果开发者决定添加新的对象类，则必须要对基类有所了解，方能支持新类。另一个问题在于所有的对象类都必须实现同样的一些底层函数。</p>
<p>　　对于第二个问题，可以通过接口继承的方式来避免基类的方法太多。在mangos的实现中就采用了类似的方法，从Object虚基类派生的Unit和WorldObject仍然还是不可实例化的类，这两种对象定义了不同的属性和方法，分来实现不同类型的对象。在游戏内部可以根据对象的实际类型来Object指针向下转型为Unit或WorldObject，以调用需要的接口。方法虽然不够OO，也还能解决问题。但是第一个问题是始终无法避免的。</p>
<p>　　所以我们便有了通用实体这么一个概念，其主要方法是将原来基类的接口进行分类，分到一个个不同的子类中，然后以对象组合的方式来生成我们所需要的实际游戏对象类型。这个组合的过程可以通过脚本定义的方式，这样便可以在运行时生成为同的对象类型，也就解决了上面提到的第一个问题。</p>
<p>　　通用实体的实现方法在目前的游戏引擎及开源代码中也可以看到影子。一个是BigWorld，从提供的资料来看，其引擎只提供了一个entity游戏对象，然后由游戏内容实现者通过xml和python脚本来自由定义不同类型的entity类型，每种类型可有不同的property和不同的方法。这样原来由基类定义的接口完全转移到脚本定义，具有非常强的灵活性。</p>
<p>　　另外还有一个是CEL中的entity实现。按照CEL的描述，entity可以是游戏中的任意对象，包括玩家可交互的对象，如钥匙、武器等，也可以包括不能直接交互的对象，如游戏世界，甚至任务链中的一部分等。entity本身并没有任何特性，具体的功能实现需要靠附加property来完成。简单来说，property才定义了entity可以做什么，至于该怎么做，那又是依靠behavior来定义。所以，最终在CEL中一个游戏对象其实是由entity组合了多个property及多个behavior而生成的。</p>
<p>　　但是CEL中的property与BigWorld中的property意义不大一样，在CEL中可定义的property其实是引擎内部要先提供的，比如其示例中所举的pcobject.mesh、pcmove.linear、pctools.inventory等，而BigWorld中的property是完全的自由定制。从这个角度来讲，其实可以把CEL中的property看作是游戏的逻辑系统，也就是我们上面所描述的，接口分类后所定义的子类。</p>
<p>　　由引擎内部提供可选择的property与BigWorld所采用的完全自由定制property其实本质上是相同的。在用BigWorld实现的游戏中，也不可能为每种游戏对象类型都完全从头定义property，基于代码利用的原则，也会先定义一些小类，然后在entity类型定义时以自定义property的方式来包含这些小类。当然，我没有使用过BigWorld，上面的描述也只是基于游戏实现的大原则所做出来的。</p>
<p>　　描述的依然有些抽象，我们可以用wow及mangos代码来说明一下。mangos中为object定义了一个属性集合，根据对象类型的不同，这个属性集的大小及保存数据也会有差异，另外游戏对象内部含有处理不同游戏逻辑的系统，如RestSystem、FloodFilterSystem、VariousSystem等等，在player.h中以接口组的方式进行定义。</p>
<p>　　如果要将这种结构改为我们描述的通用entity系统，可以让object只提供property注册和删除的接口，这里的property定义与CEL中的相同，放在mangos中也就是上面说的RestSystem、FloodFilterSystem、VariousSystem这些。然后也通过xml文件的方式定义我们所需要的游戏对象类型，如player,creature,item等，不同的对象类型可以选择加载不同的property，加载的原则是需要哪些功能就加载哪些property。</p>
<p>　　对象的定义按上面的方法完成后，对象的实现也需要做一些修改。以前客户端的消息是直接交由player来处理，AI也是直接调用creature的接口来完成一些功能，现在通用的entity内部已经没有任何可用的方法，所有的实现都转到了property中，所以需要由各个property实现自己来注册感兴趣的事件及消息，entity实现一个消息的转发，转给对此感兴趣的property来处理。其余的实现就没有什么不同了。</p>
<p>　　当然，我们再做一点扩展，让property不光由引擎来提供，用脚本本身也能定义property，并且可以通过xml来注册这些property，这样便实现了与BigWorld一样的完全自由特性。这其实也就是将很多用C++实现的功能转移到了python中，这种做法可作为参考，但不一定对所有人合适，至少在我看来，这样的实现也基本只能由程序员来做，所以让程序员选择自己最擅长的语言可能会更易于开发和调试。</p>
<p>有关游戏对象实现的描述，前面两篇文章中说的不甚清楚，主要是一直都要引用网上能够找到的资料来进行描述，以避免与公司引起不必要的麻烦。所以语言有些拼凑的感觉，举的例子也很不恰当，今天正好看到了游戏编程精粹五和六上的两篇文章，内容都差不多，&lt;&lt;基于组件的对象管理&gt;&gt;和&lt;&lt;基于组件的游戏对象系统&gt;&gt;，说的也是我上两篇文章想要描述的内容，所以再补一篇，引用其中的部分文字进行明确的说明。</p>
<p>&nbsp;</p>
<p>　　传统的游戏对象管理系统采用继承的方式来实现，例如，所有的子类都从CObject派生。大多数情况下，直接派生的也是抽象类，其中带一些功能而另一些子类则不带这些功能，比如可控制/不可控制，可动画/不可动画等。mangos的实现中基本就是这种情况，从Object直接派生的Unit和WorldObject都是不可直接实例化的类。</p>
<p>　　传统方法的问题在于无法应对需求的变化，如要求武器也有动画效果时就无法处理了。如果硬要是这样做，那随着需求的啬，很多的方法会被放到基类中，最终的结果是继承树变得越来越头重脚轻，这样的类会丧失它的内聚性，因为它们试图为所有对象完成所有的事。</p>
<p>　　就是说到最后，基类会有一个很长的接口列表，而很多的游戏对象类型根本不需要实现其中的一些甚至大部分接口，但是按照这种结构却又必须去实现。以至于于实现一个非常庞大的对象，而且想要修改一点功能会导致系统的大调整。</p>
<p>　　我们希望的系统是可以将现有的功能组合到新的对象中，并且在将新的功能添加到现有的对象中时不需要重构大量的代码和调整继承树的结构。</p>
<p>　　实现的方法就是从组件来创建一个对象。组件是一个包含所有相关数据成员和方法的类，它完成某个特定的任务。把几个组件组合在一起就可以创建一个新的对象。如把Entity组件、Render组件和Collectable组件组合在一起生成了一个Spoon对象。Entity组件让我们可以把对象放到游戏世界中，Render组件让我们可以为对象指定一个模型进行渲染，而Collectable组件让我们可以拾取这个对象。</p>
<p>　　关于组件的实现，所有的组件都从一个基础组件接口派生，可称其为IComponent。每个组件也有自己的接口定义，并且这个接口也需要从IComponent派生，类似于这样：IComponent -- ICmpRender -- CCmpRender</p>
<p>　　这里的每个组件也就是我在上一篇中所说的由引擎提供的属性，或者说在BigWorld中自己实现然后定义的属性，或者使用mangos中的定义，就是一个个的System，虽然mangos并没有将其完全做成组件，但是通过其代码注释可以看到，接口也是按功能组进行了分类，如果要拆分成组件也是比较方便的。</p>
<p>　　组件之间的通信有两种方法，一是用组件ID查询到组件接口指针，然后调用接口方法；二是使用消息的方式，向对象中所有组件发消息。在初始化的时候，每一个组件类型都会告诉对象管理器应该接收什么样的消息。</p>
<p>　　查询接口的方法也就是直接的方法调用，只不过接口不是全部在基类中，所以必须先查询到指定的组件然后才能调用其接口。消息的使用前面已经说过多次，其实现方案也有过说明。</p>
<p>　　最后是关于游戏对象功能的扩展和游戏对象的定义。需要扩展功能也就是需要实现一个新的组件，或者修改现在组件。在大多数情况下，扩展都不会引起结构的很大调整，受影响的最多只是使用到该组件的部分代码。</p>
<p>　　游戏对象定义可采用完全数据驱动的方式，使用xml或者脚本语言来定义对象类型，以及每个类型需要加载的组件。对象类型注册到对象管理器后，由管理器提供创建指定类型的对象的方法。数据驱动的方式能够让策划自由定义游戏对象类型，并且随时可自由创建新的对象类型。</p>
</div>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113341.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-23 16:06 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/23/113341.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转【游戏开发】MMORPG服务器架构</title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113221.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 15:17:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113221.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113221.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113221.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113221.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113221.html</trackback:ping><description><![CDATA[<p>一个比较抽象的MMORPG服务器架构，简单描述。 <br>登录分配服务器：游戏区唯一入口点，根据登录服务器负载和排队情况，分配登录玩家到指定登录服务器中进行登录；<br>登录服务器：处理玩家验证身份合法性，及游戏选游戏世界操作，控制服务器人数；<br>数据服务器：处理玩家数据读取，保存和缓存的地方； <br>世界服务器：整个游戏时间的中心管理数据的服务器； <br>游戏服务器：处理玩家主逻辑的服务器； <br>道具服务器：处理所有直接道具相关逻辑的服务器，管理道具的产生消亡，交易，合成，升级，等操作；<br>网关服务器：提供给玩家与游戏服务器的中转服务器，玩家一旦登录游戏，始终处于一个网关服务器；<br>聊天服务器：提供更丰富的聊天形式，消息优化，转发。<br>中心验证服务器：与登录服务器通信，主要进行玩家身份验证，及反馈用户信息。<br>中心计费服务器：充值，扣费，交易操作的处理。</p>
<p><br>本文来自CSDN博客，转载请标明出处：<a href="http://blog.csdn.net/olncy/archive/2008/12/15/3520572.aspx"><u><font color=#0000ff>http://blog.csdn.net/olncy/archive/2008/12/15/3520572.aspx</font></u></a></p>
<div class=tit><font color=#ff0000 size=4><strong>一个高性能MMORPG网络游戏的架构实例</strong></font></div>
<div class=date>
<p><a href="http://hi.baidu.com/ahidef/blog/item/197a458ecc3b03f3503d9238.html"><u><font color=#0000ff>http://hi.baidu.com/ahidef/blog/item/197a458ecc3b03f3503d9238.html</font></u></a></p>
</div>
<p>
<table class=FCK__ShowTableBorders style="TABLE-LAYOUT: fixed">
    <tbody>
        <tr>
            <td>
            <div class=cnt>
            <p>一、服务器组模型的选型<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 考虑到近年来计算机硬件技术的飞速发展，物理服务器的性价比得到了很大的提高，结合项目需要通过服务器组给数万玩家提供高质量服务的商业要求，经过研究对比数种服务器模型后，决定采取了上图所示的服务器组模型。</p>
            <p>&#160;</p>
            <div forimg="1"><img class=blogimg src="http://hiphotos.baidu.com/ahidef/pic/item/4f3d7935f072bf91d1a2d3f6.jpg" border=0 small="0"><br>
            <p>二、MMORPG服务器系统架构</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MMORPG大型网游服务器是使用高性能网络I/O模型配合消息队列连接各服务线程的一个非常稳定的高性能网游系统。其中消息队列系基于共享内存自行开发完成。在单服务器标准工作环境下进行测试，一台双 XEON 服务器可以非常轻松地达到为4,500用户每秒处理5,000请求，每秒处理请求数可超过225,000。</p>
            <div forimg="1">
            <p><img class=blogimg src="http://hiphotos.baidu.com/ahidef/pic/item/41baad303fa6be3feac4aff1.jpg" border=0 small="0"></p>
            <p>三、MMORPG的实现</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先，在基础建设方面，与规划现实中的城市一样，得先搭建起一系列的房屋、道路及出口、管线和诸多NPC人物等构成的基本要素和活动空间，通过在服务器端(Server side)取得预先设计好的综合地理、NPC人物、技能等一系列的初始化数字数据(具体文档片段请见附件A.地图数据文件示例和附件B.司机 NPC 数据文件示例)，然后依靠程序将数字数据和游戏逻辑有机地协调起来，最终形成一套完整的虚拟游戏基础空间。</p>
            <p>&#160;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在确定了地图数据生成规则后，就可以使用编辑器任意编辑游戏场景。依赖于这样良好的基础设施，才能在其他游戏逻辑的配合下实现完整的故事情节。同时服务器端负责将属于用户各自的游戏逻辑数据通过验证后发送到合法的用户客户端机器里，完成客户端游戏逻辑的建立和数据同步。担负服务器与客户端通讯的是自定义格式的数据通讯封包，它就像数字神经般贯穿着整个游戏的始终。数据封包与如下4部分消息有关，它们分别为场景消息, 同步消息，主角消息和界面消息。</p>
            <p>&nbsp;&nbsp;&nbsp;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A.主角消息包括客户端所控制的角色的所有动作，包括走路，聊天、交易、战斗等。<br>&nbsp;&nbsp;&nbsp;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B.场景消息包括昼夜兴替、气候变化，一定的时间在场景里出现某些东西等，这类消息具有的特点是所有消息的发起者都是服务器，广播对象则是场景里的所有玩家。<br>&nbsp;&nbsp;&nbsp;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C.同步消息是针对发起对象是某个玩家，经过服务器广播给所有看得见他的玩家，该消息也包括所有的动作，该种消息是服务器广播给客户端的，主角消息则一般是客户端主动发给服务器端。<br>&nbsp;&nbsp;&nbsp;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; D.界面消息是服务器发给客户端的聊天消息和各种属性及状态变化的信息。</p>
            <p>&#160;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 值得一谈的还有处于网络游戏中比较重要的服务器同客户端消息广播和同步问题。其中一种方法是采取在国际上被称为 Mutual synchronization（相互同步），是一种对未来网络的前景的良好预测出来的解决方案来解决确保每个玩家在各自客户端上看到的东西大体是一样的同步问题。</p>
            <p>&#160;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先客户端需要在登录游戏的时候建立很多张广播列表，这些列表在客户端后台和服务器端要保持不定时同步。其中要建立多张列表，是因为要广播的类型包括全局信息、本地信息和远程信息等等，这些列表都是在客户端登陆的时候根据服务器发过来的消息建立好的。在建立列表的同时，还需要获得每个列表中广播对象的传输时间，并且要维护一张完整的用户状态列表在后台，也是进行不定时的和服务器进行同步，根据本地的用户状态表，可以使一部分决策由客户端来决定，当客户端发送这部分决策的时候，则直接将最终决策发送到各个广播列表里面的客户端，并对其时间进行校对，以保证每个客户端在收到的消息的时间是和本地时间进行校对过的，再采用预测补偿计算提前量的方法，计算出提前量，根据计算量确定实际行走速度，将会使同步变得非常的平滑。</p>
            <p>&#160;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其中，广播的重点就在于如何计算出广播的对象，首先在服务器端的连接结构里面增加一个广播对象的队列，该队列在客户端登陆服务器的时候由服务器传输给合法的客户端，然后由客户端自己来维护这个队列，当有人走出客户端视野的时候，由客户端主动要求服务器给那个对象发送消失的消息。</p>
            <p>&#160;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当有人走进视野的情况，则先需要客户端在每次给服务器发送更新位置的消息的时候，服务器都给该连接算出一个视野范围，然后在需要广播的时候，循环整张地图上的玩家，找到坐标在其视野范围内的玩家从而完成广播的全过程。</p>
            <p>&#160;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其次是虚拟对象系统。其中主要会涉及到NPC的概念，尤其是广泛应用的A Star算法等在提供NPC的人工智能决策方面有着重要的作用。NPC智能使用一种是被动触发事件和是主动触发事件的方式由计算机来实现对NPC做何种决策。A Star算法就是典型的启发式搜索的应用，其普通原理是先设计一个Rule() 函数，来获这一个点的代价，然后每次搜索的时候把下一步可能到达的所有点都经过Rule() 函数评价一下，获取两到三个代价比较小的点，继续搜索，直至得到代价最小的一个点。最明显的应用是NPC在实现自动选择攻击目标和逃跑时的实现。实现自动选择攻击目标时，首先获得地图上距离该NPC附近的敌人列表，设计相应Rule() 函数，根据敌人的强弱、远近，判断出几个评估数据，然后选择代价最小的敌人进行主动攻击。逃跑则是在主动事件里面检查自己的HP，如果HP低于某个值，而敌人正近战攻击的时候，则触发逃跑函数，在逃跑函数里面也是对周围的所有的敌人组织成列表，然后设计Rule() 函数，先分析选择出对你构成威胁最大的敌人，该函数还需要判断敌人的运动速度，战斗力强弱，最后得出一个主要敌人，然后针对该主要敌人进行路径的Rule() 的函数的设计，搜索的范围只可能是和主要敌人相反的方向，然后再根据该几个方向上的敌人的强弱来计算代价，做出最后的选择，如果幸运的话，可以有80%的机率逃往没有 NPC 阻挡的邻近地图中去。</p>
            <p>&#160;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 最后，由于脚本是RPG游戏的灵魂，自然脚本编译器就扮演了十分重要的地位。在基于编译的服务器端程序中，是无法在程序的运行过程中构建一些东西的，所以必须通过脚本编译器提供一些简单的语法和文法解析的功能，进行一系列的逻辑判断和循环，以提高服务器端的灵活程度。可使用类似汇编语言的那种结构来实现脚本编译器，设置一些条件跳转和循环来实现逻辑判断和循环。提供一些通用指令，如判断、循环、四则运算、寻址等等，针对不同的脚本采用不同的解析方法，对NPC就用NPC固定的脚本，对Item就用Item固定的脚本，解析完以后就把结果生成底层该对象的结构便于使用。</p>
            <p>&#160;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 经过以上的建设步骤，一个完整的MMORPG网络游戏系统就被逐步建立起来了。</p>
            <p>ZZ <a class=ln href="http://groups.google.com/group/mmorpgdna"><u><font color=#0000ff>MDNA网络游戏整体架构编程</font></u></a></p>
            </div>
            </div>
            </div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113221.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 23:17 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113221.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转【游戏开发】利用CEGUI+Lua实现灵活的游戏UI框架</title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113217.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 15:13:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113217.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113217.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113217.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113217.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113217.html</trackback:ping><description><![CDATA[<table style="TABLE-LAYOUT: fixed; WIDTH: 100%">
    <tbody>
        <tr>
            <td>
            <div class=cnt id=blog_text>
            <p><a href="http://blog.csdn.net/Lodger007/archive/2007/12/09/1926057.aspx"><u><font color=#0000ff>利用CEGUI+Lua实现灵活的游戏UI框架</font></u></a></p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在上一篇文章中，介绍了一种基于组件方式的游戏UI架构设计方案，在这里，笔者将介绍如何利用CEGUI和Lua来实现这种灵活的框架。</p>
            <div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CEGUI</span>是一个兼容OpenGL、DirectX的优秀开源GUI库，关于她的介绍以及如何在Direct3D中使用她，可以参考<a href="http://blog.csdn.net/Lodger007/archive/2007/07/02/1675141.aspx"><font color=#336699><u>http://blog.csdn.net/Lodger007/archive/2007/07/02/1675141.aspx</u></font></a>一文。Lua是一种强大的脚本语言，她使用栈作为数据接口，能够很容易地与其它语言交互，关于她的介绍可以参考<a href="http://www.lua.org/"><font color=#336699><u>http://www.lua.org/</u></font></a>，以及笔者以前翻译的三篇系列文章：Lua入门（<a href="http://blog.csdn.net/Lodger007/archive/2006/06/26/836466.aspx"><font color=#336699><u>http://blog.csdn.net/Lodger007/archive/2006/06/26/836466.aspx</u></font></a>）、调用Lua函数（<a href="http://blog.csdn.net/Lodger007/archive/2006/06/26/836897.aspx"><font color=#336699><u>http://blog.csdn.net/Lodger007/archive/2006/06/26/836897.aspx</u></font></a>）、在Lua中调用C++函数（<a href="http://blog.csdn.net/Lodger007/archive/2006/06/26/837349.aspx"><font color=#336699><u>http://blog.csdn.net/Lodger007/archive/2006/06/26/837349.aspx</u></font></a>）。</div>
            <div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>在实现中，作为UI组件管理器的GUISystem是一个单件，这样，你能够很方便地在任何地方使用其全局唯一的对象。下面是Singleton和GUISystem的实现代码：</div>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113217.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 23:13 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113217.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]c++调用lua脚本1（平台windows） </title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113193.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 15:00:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113193.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113193.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113193.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113193.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113193.html</trackback:ping><description><![CDATA[&nbsp;通过c++调用lua 脚本，<br>&nbsp;&nbsp;&nbsp; 环境VC++6.0<br>&nbsp;&nbsp;&nbsp; lua&nbsp; sdk 5.1<br><br><br>&nbsp;&nbsp; 在调用前 先认识几个函数。<br>1． 调用lua_open()将创建一个指向Lua解释器的指针。 <br>2． luaL_openlibs()函数加载Lua库。 <br>3． 使用luaL_dofile()加载脚本并运行脚本。 <br>4． lua_close()来关闭Lua指向解释器的指针。<br>&nbsp;<br>5． 调用lua_getglobal()将add()函数压入栈顶，add()为lua函数。<br>6． 第一个参数x，通过调用lua_pushnumber()入栈。<br>7． 再次调用lua_pushnumber()将第二个参数入栈。<br>8． 使用lua_call()调用Lua函数。<br>9． 调用lua_tonumber()从栈顶取得函数的返回值。<br>10． lua_pop()移除栈顶的值。<br><br><br>代码<br>add.lua
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">1</span><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">function&nbsp;add&nbsp;(&nbsp;x,&nbsp;y&nbsp;)<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;x&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;y<br></span><span style="COLOR: #008080">3</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>end<br></span><span style="COLOR: #008080">4</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<br>main.cpp<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">stdio.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img id=Codehighlighter1_31_91_Open_Image onclick="this.style.display='none'; Codehighlighter1_31_91_Open_Text.style.display='none'; Codehighlighter1_31_91_Closed_Image.style.display='inline'; Codehighlighter1_31_91_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_31_91_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_31_91_Closed_Text.style.display='none'; Codehighlighter1_31_91_Open_Image.style.display='inline'; Codehighlighter1_31_91_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span style="COLOR: #0000ff">extern</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">C</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span id=Codehighlighter1_31_91_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_31_91_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">lua.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">lualib.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">lauxlib.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img id=Codehighlighter1_94_118_Open_Image onclick="this.style.display='none'; Codehighlighter1_94_118_Open_Text.style.display='none'; Codehighlighter1_94_118_Closed_Image.style.display='inline'; Codehighlighter1_94_118_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_94_118_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_94_118_Closed_Text.style.display='none'; Codehighlighter1_94_118_Open_Image.style.display='inline'; Codehighlighter1_94_118_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_94_118_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id=Codehighlighter1_94_118_Open_Text><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">&nbsp;the&nbsp;Lua&nbsp;interpreter&nbsp;</span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>lua_State&nbsp;&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;L;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;luaadd&nbsp;(&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;x,&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;y&nbsp;)<br><img id=Codehighlighter1_165_388_Open_Image onclick="this.style.display='none'; Codehighlighter1_165_388_Open_Text.style.display='none'; Codehighlighter1_165_388_Closed_Image.style.display='inline'; Codehighlighter1_165_388_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_165_388_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_165_388_Closed_Text.style.display='none'; Codehighlighter1_165_388_Open_Image.style.display='inline'; Codehighlighter1_165_388_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_165_388_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_165_388_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;sum;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">函数名</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;lua_getglobal(L,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">add</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">第一个参数压栈</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;lua_pushnumber(L,&nbsp;x);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">第二个参数压栈</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;lua_pushnumber(L,&nbsp;y);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">调用函数</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;lua_call(L,&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">得到返回值</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">)lua_tonumber(L,&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;lua_pop(L,&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;sum;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main&nbsp;(&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">argv[]&nbsp;)<br><img id=Codehighlighter1_427_684_Open_Image onclick="this.style.display='none'; Codehighlighter1_427_684_Open_Text.style.display='none'; Codehighlighter1_427_684_Closed_Image.style.display='inline'; Codehighlighter1_427_684_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_427_684_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_427_684_Closed_Text.style.display='none'; Codehighlighter1_427_684_Open_Image.style.display='inline'; Codehighlighter1_427_684_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_427_684_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_427_684_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;sum;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">创建一个指向Lua解释器的指针。</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;L&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;lua_open();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">函数加载Lua库</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;luaL_openlibs(L);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">加载脚本</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;luaL_dofile(L,</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">add.lua</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">调用函数</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;luaadd(&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;print&nbsp;the&nbsp;result&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;printf(&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">The&nbsp;sum&nbsp;is&nbsp;%d\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;sum&nbsp;);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">关闭&nbsp;释放资源&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;lua_close(L);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<br><br>注意问题：<br>1.工程头文件lua.h等，编译器能找到，可以通过工具来设置头文件路径。<br>2. 添加lua5.1.lib到Object/library modules列表中。 <br><br>测试结果<br>The sum is 21<br><br>关于lua的认识<br><a href="http://www.cppblog.com/expter/archive/2008/12/24/70224.html"><font color=#000080>http://www.cppblog.com/expter/archive/2008/12/24/70224.html</font></a> 
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113193.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 23:00 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113193.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转经典塔防游戏TowersTrap-[lua复刻版本,附全部lua源代码]</title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113192.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 14:57:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113192.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113192.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113192.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113192.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113192.html</trackback:ping><description><![CDATA[<div id=att_91 style="MARGIN: 5px">图片： <br><img onclick=" window.open('http://bbs.luaer.cn/attachment/5_3266_1e9a269c9fab601.jpg');" alt="Click Here To EnLarge" src="http://bbs.luaer.cn/attachment/thumb/5_3266_1e9a269c9fab601.jpg" onload="if(this.width>'700')this.width='700';if(this.height>'700')this.height='700';" border=0> </div>
<div class=tpc_content id=read_tpc>经典塔防游戏TowersTrap<br><br>这是个很经典的塔防游戏，非常耐玩， 喜欢的朋友可以试试。 <br><br>游戏介绍： 玩过魔兽的朋友应该对这个不陌生了，游戏中只有一个出口，游戏有多个难度选择，玩家必须在"怪"到达出口之前消灭它们。<br><br>操作介绍：先确定塔的类型，然后在图中任意位置放下。点击已建造的塔后塔的上下会出现数字，分别是升级和出售的价钱，升级塔也很重要哦~ <br><br><br>安装说明： <br>1.下载安装游戏引擎love2d<br><a href="http://www.love2d.org/download" target=_blank><u><font color=#0000ff>http://www.love2d.org/download</font></u></a><br>2.下载游戏<span id=rlt_1 style="CURSOR: pointer; BORDER-BOTTOM: #fa891b 1px solid" onclick="sendmsg('pw_ajax.php','action=relatetag&amp;tagname=文件',this.id)">文件</span> <br><a href="http://219.136.249.30/svn_readonly/towerstrap/dist/towerstrap.love" target=_blank><u><font color=#0000ff>http://219.136.249.30/svn_readonly/towerstrap/dist/towerstrap.love</font></u></a> <br><br>3.游戏下载到任意目录后(注意,love2d引擎不支持中文目录),双击towerstrap.love文件就可以开始游戏了<br><br>源代码：<br>svn:<br><a href="http://219.136.249.30/svn_readonly/towerstrap/" target=_blank><u><font color=#0000ff>http://219.136.249.30/svn_readonly/towerstrap/</font></u></a><br>交流请加qq群:阿兜明@83086500</div>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113192.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 22:57 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113192.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lua脚本语法说明（修订）</title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113190.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 14:55:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113190.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113190.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113190.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113190.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113190.html</trackback:ping><description><![CDATA[Lua脚本语法说明（增加lua5.1部份特性）<br><br>　　Lua 的语法比较简单，学习起来也比较省力，但功能却并不弱。<br>　　所以，我只简单的归纳一下Lua的一些语法规则，使用起来方便好查就可以了。估计看完了，就懂得怎么写Lua程序了。<br><br>　　在Lua中，一切都是变量，除了关键字。<br><br>I.&nbsp; 首先是注释<br>　　写一个程序，总是少不了注释的。<br>　　在Lua中，你可以使用单行注释和多行注释。<br>　　单行注释中，连续两个减号"--"表示注释的开始，一直延续到行末为止。相当于C++语言中的"//"。<br>　　多行注释中，由"--[["表示注释开始，并且一直延续到"]]"为止。这种注释相当于C语言中的"/*...*/"。在注释当中，"[["和"]]"是可以嵌套的（<span style="COLOR: red">在lua5.1中，中括号中间是可以加若干个"="号的，如 [==[ ... ]==]</span>），见下面的字符串表示说明。<br><br>II.&nbsp; Lua编程<br>　　经典的"Hello world"的程序总是被用来开始介绍一种语言。在Lua中，写一个这样的程序很简单：<br>　　print("Hello world")<br>　　在Lua中，语句之间可以用分号"；"隔开，也可以用空白隔开。一般来说，如果多个语句写在同一行的话，建议总是用分号隔开。<br>　　Lua 有好几种程序控制语句，如：<br>
<table style="WIDTH: 760px; BORDER-COLLAPSE: collapse; HEIGHT: 124px" cellSpacing=0 cellPadding=3 border=1>
    <tbody>
        <tr>
            <td style="COLOR: red">控制语句</td>
            <td style="COLOR: red">格式</td>
            <td style="COLOR: red">示例</td>
        </tr>
        <tr>
            <td style="WIDTH: 80px">If</td>
            <td style="WIDTH: 313px; HEIGHT: 44px">if 条件 then ... elseif 条件 then ... else ... end</td>
            <td>
            <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000">&nbsp;print(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">true</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #0000ff">elseif</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">then</span><span style="COLOR: #000000">&nbsp;print(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">true</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">&nbsp;print(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">false</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #0000ff">end</span></div>
            <br></td>
        </tr>
        <tr>
            <td>While</td>
            <td>while 条件 do ... end</td>
            <td>
            <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000">&nbsp;print(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">true</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #0000ff">end</span></div>
            <br></td>
        </tr>
        <tr>
            <td>Repeat</td>
            <td>repeat ... until 条件</td>
            <td>
            <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000"><span style="COLOR: #2000ff">repeat</span>&nbsp;</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">(</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="FONT-WEIGHT: bold; COLOR: #000000">Hello</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #0000ff">until</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">1</span><span style="COLOR: #000000">+</span><span style="COLOR: #800000">1</span><span style="COLOR: #000000">~=</span><span style="COLOR: #800000">2</span></div>
            <br></td>
        </tr>
        <tr>
            <td>For</td>
            <td>for 变量=初值, 终点值, 步进 do&nbsp;... end</td>
            <td>
            <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000">&nbsp;print(i)&nbsp;</span><span style="COLOR: #0000ff">end</span></div>
            <br></td>
        </tr>
        <tr>
            <td>For</td>
            <td>for 变量1, 变量2, ... 变量n in 表或枚举函数 do ... end</td>
            <td>
            <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;a,b&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;mylist&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">(a,&nbsp;b)&nbsp;</span><span style="COLOR: #0000ff">end</span></div>
            <br></td>
        </tr>
    </tbody>
</table>
<br>　　注意一下，for的循环变量总是只作用于for的局部变量；当省略步进值时，for循环会使用1作为步进值。<br>　　使用break可以用来中止一个循环。<br>　　相对C语言来说，Lua有几个地方是明显不同的，所以面要特别注意一下：<br><br>　　．<strong>语句块</strong><br>　　　　语句块在C中是用"{"和"}"括起来的，在Lua中，它是用do 和 end 括起来的。比如：<br>　　　　do print("Hello") end<br>　　　　可以在 <strong>函数</strong> 中和 <strong>语句块</strong> 中定局部变量。<br><br>　　．<strong>赋值语句</strong><br>　　　　赋值语句在Lua被强化了。它可以同时给多个变量赋值。<br>　　　　例如：<br>　　　　a,b,c,d=1,2,3,4<br>　　　　甚至是：<br>　　　　a,b=b,a&nbsp; -- 多么方便的交换变量功能啊。<br>　　　　在默认情况下，变量总是认为是全局的。假如需要定义局部变量，则在第一次赋值的时候，需要用local说明。比如：<br>　　　　local a,b,c = 1,2,3&nbsp; -- a,b,c都是局部变量<br><br>　　．<strong>数值运算</strong><br>　　　　和C语言一样，支持 +, -, *, /。但Lua还多了一个"^"。这表示指数乘方运算。比如2^3 结果为8, 2^4结果为16。<br>　　　　连接两个字符串，可以用".."运处符。如：<br>　　　　"This a " .. "string." -- 等于 "this a string"<br><br>　　．<strong>比较运算<br></strong>
<table style="WIDTH: 543px; BORDER-COLLAPSE: collapse; HEIGHT: 70px" cellSpacing=0 cellPadding=3 border=1>
    <tbody>
        <tr>
            <td style="COLOR: red">比较符号</td>
            <td>&lt;</td>
            <td>&gt;</td>
            <td>&lt;=</td>
            <td>&gt;=</td>
            <td>==</td>
            <td>~=</td>
        </tr>
        <tr>
            <td style="COLOR: red">含义</td>
            <td>小于</td>
            <td>大于</td>
            <td>小于或等于</td>
            <td>大于或等于</td>
            <td>相等</td>
            <td>不相等</td>
        </tr>
    </tbody>
</table>
<br>　　　　所有这些操作符总是返回true或false。<br>　　　　对于Table，Function和Userdata类型的数据，只有 == 和 ~=可以用。相等表示两个变量引用的是同一个数据。比如：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">　　　　a</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">{</span><span style="FONT-WEIGHT: bold; COLOR: #800000">1</span><span style="COLOR: #000000">,</span><span style="FONT-WEIGHT: bold; COLOR: #800000">2</span><span style="COLOR: #000000">}<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　b</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">a<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">(a</span><span style="COLOR: #808080">==</span><span style="COLOR: #000000">b,&nbsp;a</span><span style="COLOR: #808080">~=</span><span style="COLOR: #000000">b)&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">输出&nbsp;true,&nbsp;false</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">　　　　a</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">{</span><span style="FONT-WEIGHT: bold; COLOR: #800000">1</span><span style="COLOR: #000000">,</span><span style="FONT-WEIGHT: bold; COLOR: #800000">2</span><span style="COLOR: #000000">}<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　b</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">{</span><span style="FONT-WEIGHT: bold; COLOR: #800000">1</span><span style="COLOR: #000000">,</span><span style="FONT-WEIGHT: bold; COLOR: #800000">2</span><span style="COLOR: #000000">}<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">(a</span><span style="COLOR: #808080">==</span><span style="COLOR: #000000">b,&nbsp;a</span><span style="COLOR: #808080">~=</span><span style="COLOR: #000000">b)&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">输出&nbsp;false,&nbsp;true</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<br><br>　　．逻辑运算<br>　　　　and, or, not<br>　　　　其中，and 和 or 与C语言区别特别大。<br>　　　　在这里，请先记住，在Lua中，只有false和nil才计算为false，其它任何数据都计算为true，0也是true！<br>　　　　and 和 or的运算结果不是true和false，而是和它的两个操作数相关。<br>　　　　a and b：如果a为false，则返回a；否则返回b<br>　　　　a or b：如果 a 为true，则返回a；否则返回b<br><br>　　　　举几个例子：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">　　　　&nbsp;</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">(</span><span style="FONT-WEIGHT: bold; COLOR: #800000">4</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #808080">and</span><span style="COLOR: #000000">&nbsp;</span><span style="FONT-WEIGHT: bold; COLOR: #800000">5</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">输出&nbsp;5</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">　　　　&nbsp;</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">(nil&nbsp;</span><span style="COLOR: #808080">and</span><span style="COLOR: #000000">&nbsp;</span><span style="FONT-WEIGHT: bold; COLOR: #800000">13</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">输出&nbsp;nil</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">　　　　&nbsp;</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">(false&nbsp;</span><span style="COLOR: #808080">and</span><span style="COLOR: #000000">&nbsp;</span><span style="FONT-WEIGHT: bold; COLOR: #800000">13</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">输出&nbsp;false</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">　　　　&nbsp;</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">(</span><span style="FONT-WEIGHT: bold; COLOR: #800000">4</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #808080">or</span><span style="COLOR: #000000">&nbsp;</span><span style="FONT-WEIGHT: bold; COLOR: #800000">5</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">输出&nbsp;4</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">　　　　&nbsp;</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">(false&nbsp;</span><span style="COLOR: #808080">or</span><span style="COLOR: #000000">&nbsp;</span><span style="FONT-WEIGHT: bold; COLOR: #800000">5</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">输出&nbsp;5</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<br>　　　　在Lua中这是很有用的特性，也是比较令人混洧的特性。<br>　　　　我们可以模拟C语言中的语句：x = a? b : c，在Lua中，可以写成：x = a and b or c。<br>　　　　最有用的语句是： x = x or v，它相当于：if not x then x = v end 。<br><br>　　．运算符优先级，从低到高顺序如下：<br>
<table style="WIDTH: 320px; BORDER-COLLAPSE: collapse" cellSpacing=0 cellPadding=3 border=1>
    <tbody>
        <tr>
            <td>&nbsp;&nbsp;&nbsp;&nbsp; or<br>&nbsp;&nbsp;&nbsp;&nbsp; and<br>&nbsp;&nbsp;&nbsp;&nbsp; &lt;&nbsp;&nbsp;&nbsp;&nbsp; &gt;&nbsp;&nbsp;&nbsp;&nbsp; &lt;=&nbsp;&nbsp;&nbsp; &gt;=&nbsp;&nbsp;&nbsp; ~=&nbsp;&nbsp;&nbsp; ==<br>&nbsp;&nbsp;&nbsp;&nbsp; .. (字符串连接)<br>&nbsp;&nbsp;&nbsp;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp; -<br>&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp; /&nbsp;&nbsp;&nbsp;&nbsp; %<br>&nbsp;&nbsp;&nbsp;&nbsp; not&nbsp;&nbsp; #(<span style="COLOR: red">lua5.1 取长度运算</span>)&nbsp;&nbsp;&nbsp;&nbsp; - (一元运算)<br>&nbsp;&nbsp;&nbsp;&nbsp; ^</td>
        </tr>
    </tbody>
</table>
和C语言一样，括号可以改变优先级。<br><br>III.&nbsp; 关键字<br>　　关键字是不能做为变量的。Lua的关键字不多，就以下几个：<br>&nbsp;&nbsp;&nbsp;&nbsp;
<table style="WIDTH: 426px; BORDER-COLLAPSE: collapse; HEIGHT: 105px" cellSpacing=0 cellPadding=3 border=1>
    <tbody>
        <tr>
            <td>and</td>
            <td>break</td>
            <td>do</td>
            <td>else</td>
            <td>elseif</td>
            <td></td>
        </tr>
        <tr>
            <td>end</td>
            <td>false</td>
            <td>for</td>
            <td>function</td>
            <td>if</td>
            <td></td>
        </tr>
        <tr>
            <td>in</td>
            <td>local</td>
            <td>nil</td>
            <td>not</td>
            <td>or</td>
            <td></td>
        </tr>
        <tr>
            <td>repeat</td>
            <td>return</td>
            <td>then</td>
            <td>true</td>
            <td>until</td>
            <td>while</td>
        </tr>
    </tbody>
</table>
<br>IV.&nbsp; 变量类型<br>　　怎么确定一个变量是什么类型的呢？大家可以用type()函数来检查。Lua支持的类型有以下几种：<br>
<table style="WIDTH: 758px; BORDER-COLLAPSE: collapse; HEIGHT: 143px" cellSpacing=0 cellPadding=3 border=1>
    <tbody>
        <tr>
            <td style="WIDTH: 74px">Nil</td>
            <td>空值，所有没有使用过的变量，都是nil。nil既是值，又是类型。</td>
        </tr>
        <tr>
            <td>Boolean</td>
            <td>布尔值，只有两个有效值：true和false</td>
        </tr>
        <tr>
            <td>Number</td>
            <td>数值，在Lua里，数值相当于C语言的double</td>
        </tr>
        <tr>
            <td>String</td>
            <td>字符串，如果你愿意的话，字符串是可以包含"\0"字符的（这和C语言总是以"\0"结尾是不一样的）</td>
        </tr>
        <tr>
            <td>Table</td>
            <td>关系表类型，这个类型功能比较强大，请参考后面的内容。</td>
        </tr>
        <tr>
            <td>Function</td>
            <td>函数类型，不要怀疑，函数也是一种类型，也就是说，所有的函数，它本身就是一个变量。</td>
        </tr>
        <tr>
            <td>Userdata</td>
            <td>嗯，这个类型专门用来和Lua的宿主打交道的。宿主通常是用C和C++来编写的，在这种情况下，Userdata可以是宿主的任意数据类型，常用的有Struct和指针。</td>
        </tr>
        <tr>
            <td>Thread</td>
            <td><span style="TEXT-DECORATION: line-through">线程类型，在Lua中没有真正的线程。Lua中可以将一个函数分成几部份运行。</span>如果感兴趣的话，可以去看看Lua的文档。<br>现在回过头来看看，倒觉得不是线程类型。反而象是用来做遍历的，象是Iterator函数。<br>如：<br>
            <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;range(n)<br>&nbsp; <span style="COLOR: #2000ff">local</span> i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;n)&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"></span> <br>&nbsp;&nbsp;&nbsp; coroutine.yield( i )<br><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">end</span></div>
            可惜的是要继续运行，需要coroutine.resume函数，有点鸡肋。请指教。<br></td>
        </tr>
    </tbody>
</table>
<br>V.&nbsp; 变量的定义<br>　　所有的语言，都要用到变量。在Lua中，不管在什么地方使用变量，都不需要声明，并且所有的这些变量总是全局变量，除非我们在前面加上"local"。这一点要特别注意，因为我们可能想在函数里使用局部变量，却忘了用local来说明。<br>　　至于变量名字，它是大小写相关的。也就是说，A和a是两个不同的变量。<br>　　定义一个变量的方法就是赋值。"＝"操作就是用来赋值的<br>　　我们一起来定义几种常用类型的变量吧。<br>　　A.&nbsp; Nil<br>　　　　正如前面所说的，没有使用过的变量的值，都是Nil。有时候我们也需要将一个变量清除，这时候，我们可以直接给变量赋以nil值。如：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">　　　　var1</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">nil&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">&nbsp;请注意&nbsp;nil&nbsp;一定要小写</span></div>
<br>　　B.&nbsp; Boolean<br>　　　　布尔值通常是用在进行条件判断的时候。布尔值有两种：true 和 false。在Lua中，只有false和nil才被计算为false，而所有任何其它类型的值，都是true。比如0，空串等等，都是true。不要被 C语言的习惯所误导，0在Lua中的的确确是true。你也可以直接给一个变量赋以Boolean类型的值，如：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">　　　　theBoolean&nbsp;</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">&nbsp;true</span></div>
<br>　　C.&nbsp; Number<br>　　　　在Lua中，是没有整数类型的，也不需要。一般情况下，只要数值不是很大（比如不超过100,000,000,000,000），是不会产生舍入误差的。在WindowsXP能跑的当今主流PC上，实数的运算并不比整数慢。<br>　　　　实数的表示方法，同C语言类似，如：<br>　　　　4 0.4 4.57e-3 0.3e12 5e+20<br><br>　　D.&nbsp; String<br>　　　　字符串，总是一种非常常用的高级类型。在Lua中，我们可以非常方便的定义很长很长的字符串。<br>　　　　字符串在Lua中有几种方法来表示，最通用的方法，是用双引号或单引号来括起一个字符串的，如：<br>　　　　"That's go!"<br>　　　　或<br>　　　　'Hello world!'<br><br>　　　　和C语言相同的，它支持一些转义字符，列表如下：<br>　　　　\a&nbsp; bell<br>　　　　\b&nbsp; back space<br>　　　　\f&nbsp; form feed<br>　　　　\n&nbsp; newline<br>　　　　\r&nbsp; carriage return<br>　　　　\t&nbsp; horizontal tab<br>　　　　\v&nbsp; vertical tab<br>　　　　\\&nbsp; backslash<br>　　　　\"&nbsp; double quote<br>　　　　\"&nbsp; single quote<br>　　　　\[&nbsp; left square bracket<br>　　　　\]&nbsp; right square bracket<br><br>　　　　由于这种字符串只能写在一行中，因此，不可避免的要用到转义字符。加入了转义字符的串，看起来实在是不敢恭维，比如：<br>　　　　"one line\nnext line\n\"in quotes\", "in quotes""<br>　　　　一大堆的"\"符号让人看起来很倒胃口。如果你与我有同感，那么，我们在Lua中，可以用另一种表示方法：用"[["和"]]"将多行的字符串括起来。（<span style="COLOR: red">lua5.1: 中括号中间可以加入若干个"="号，如 [==[ ... ]==]，详见下面示例</span>）<br>　　　　示例：下面的语句所表示的是完全相同的字符串：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">a&nbsp;</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #ff0000">'</span><span style="COLOR: #ff0000">alo\n123"</span><span style="COLOR: #ff0000">'</span><span style="COLOR: #000000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>a&nbsp;</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">&nbsp;<span style="COLOR: red">"alo\n123\""</span><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>a&nbsp;</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #ff0000">'</span><span style="COLOR: #ff0000">\97lo\10\04923"</span><span style="COLOR: #ff0000">'</span><span style="COLOR: #000000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>a&nbsp;</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #ff0000">[</span><span style="COLOR: #ff0000">[alo<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>123"</span><span style="COLOR: #ff0000">]</span><span style="COLOR: #000000">]<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>a&nbsp;</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #ff0000">[</span><span style="COLOR: #ff0000">==[<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>alo<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>123"</span><span style="COLOR: #ff0000">]</span><span style="COLOR: #808080">==</span><span style="COLOR: #000000">]</span></div>
<br>　　　　值得注意的是，在这种字符串中，如果含有单独使用的"[["或"]]"就仍然得用"\["或"\]"来避免歧义。当然，这种情况是极少会发生的。<br><br>　　E.&nbsp; Table<br>　　　　关系表类型，这是一个很强大的类型。我们可以把这个类型看作是一个数组。只是C语言的数组，只能用正整数来作索引；在Lua中，你可以用任意类型来作数组的索引，除了nil。同样，在C语言中，数组的内容只允许一种类型；在Lua中，你也可以用任意类型的值来作数组的内容，除了nil。<br>　　　　Table的定义很简单，它的主要特征是用"{"和"}"来括起一系列数据元素的。比如：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">　　　　T1&nbsp;</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">&nbsp;{}&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">&nbsp;定义一个空表</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">　　　　T1</span><span style="COLOR: #ff0000">[</span><span style="COLOR: #ff0000">1</span><span style="COLOR: #ff0000">]</span><span style="COLOR: #808080">=</span><span style="FONT-WEIGHT: bold; COLOR: #800000">10</span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">&nbsp;然后我们就可以象C语言一样来使用它了。</span><span style="COLOR: #008080"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">　　　　T1</span><span style="COLOR: #ff0000">[</span><span style="COLOR: #ff0000">"John"</span><span style="COLOR: #ff0000">]</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">{Age</span><span style="COLOR: #808080">=</span><span style="FONT-WEIGHT: bold; COLOR: #800000">27</span><span style="COLOR: #000000">,&nbsp;Gender</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">"Male"}<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　这一句相当于：<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　T1</span><span style="COLOR: #ff0000">[</span><span style="COLOR: #ff0000">"John"</span><span style="COLOR: #ff0000">]</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">{}&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">&nbsp;必须先定义成一个表，还记得未定义的变量是nil类型吗</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">　　　　T1</span><span style="COLOR: #ff0000">[</span><span style="COLOR: #ff0000">"John"</span><span style="COLOR: #ff0000">][</span><span style="COLOR: #ff0000">"Age"</span><span style="COLOR: #ff0000">]</span><span style="COLOR: #808080">=</span><span style="FONT-WEIGHT: bold; COLOR: #800000">27</span><span style="COLOR: #000000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　T1</span><span style="COLOR: #ff0000">[</span><span style="COLOR: #ff0000">"John"</span><span style="COLOR: #ff0000">][</span><span style="COLOR: #ff0000">"Gender"</span><span style="COLOR: #ff0000">]</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">"Male"<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　当表的索引是字符串的时候，我们可以简写成：<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　T1.John</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">{}<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　T1.John.Age</span><span style="COLOR: #808080">=</span><span style="FONT-WEIGHT: bold; COLOR: #800000">27</span><span style="COLOR: #000000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　T1.John.Gender</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">"Male"<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　或<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　T1.John{Age</span><span style="COLOR: #808080">=</span><span style="FONT-WEIGHT: bold; COLOR: #800000">27</span><span style="COLOR: #000000">,&nbsp;Gender</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">"Male"}</span></div>
这是一个很强的特性。<br><br>　　　　在定义表的时候，我们可以把所有的数据内容一起写在"{"和"}"之间，这样子是非常方便，而且很好看。比如，前面的T1的定义，我们可以这么写：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">　　　　T1</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　{<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　　　</span><span style="FONT-WEIGHT: bold; COLOR: #800000">10</span><span style="COLOR: #000000">,&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">&nbsp;相当于&nbsp;[1]&nbsp;=&nbsp;10</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">　　　　　　</span><span style="COLOR: #ff0000">[</span><span style="COLOR: #ff0000">100</span><span style="COLOR: #ff0000">]</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">&nbsp;</span><span style="FONT-WEIGHT: bold; COLOR: #800000">40</span><span style="COLOR: #000000">,<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　　　John</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">&nbsp;如果你原意，你还可以写成：["John"]&nbsp;=</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">　　　　　　{<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　　　　　Age</span><span style="COLOR: #808080">=</span><span style="FONT-WEIGHT: bold; COLOR: #800000">27</span><span style="COLOR: #000000">,&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">&nbsp;如果你原意，你还可以写成：["Age"]&nbsp;=27</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">　　　　　　　　Gender</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">Male&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">&nbsp;如果你原意，你还可以写成：["Gender"]&nbsp;=Male</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">　　　　　　},<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　　　</span><span style="FONT-WEIGHT: bold; COLOR: #800000">20</span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">&nbsp;相当于&nbsp;[2]&nbsp;=&nbsp;20</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">　　　　}<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<br>　　　　看起来很漂亮，不是吗？我们在写的时候，需要注意三点：<br>　　　　第一，所有元素之间，总是用逗号"，"隔开；<br>　　　　第二，所有索引值都需要用"["和"]"括起来；如果是字符串，还可以去掉引号和中括号；<br>　　　　第三，如果不写索引，则索引就会被认为是数字，并按顺序自动从1往后编；<br><br>　　　　表类型的构造是如此的方便，以致于常常被人用来代替配置文件。是的，不用怀疑，它比ini文件要漂亮，并且强大的多。<br><br>　　F.&nbsp; Function<br>　　　　函数，在Lua中，函数的定义也很简单。典型的定义如下：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">　　　　</span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">add</span><span style="COLOR: #000000">(a,b)&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">&nbsp;add&nbsp;是函数名字，a和b是参数名字</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">　　　　&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;a</span><span style="COLOR: #808080">+</span><span style="COLOR: #000000">b&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">&nbsp;return&nbsp;用来返回函数的运行结果</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">　　　　</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<br>　　　　请注意，return语言一定要写在end之前。假如我们非要在中间放上一句return，那么就应该要写成：do return end。<br>　　　　还记得前面说过，函数也是变量类型吗？上面的函数定义，其实相当于：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">　　　　</span><span style="COLOR: #0000ff">add</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;(a,b)&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;a</span><span style="COLOR: #808080">+</span><span style="COLOR: #000000">b&nbsp;</span><span style="COLOR: #0000ff">end</span></div>
当重新给add赋值时，它就不再表示这个函数了。我们甚至可以赋给add任意数据，包括nil （这样，赋值为nil，将会把该变量清除）。Function是不是很象C语言的函数指针呢？<br><br>　　　　和C语言一样，Lua的函数可以接受可变参数个数，它同样是用"..."来定义的，比如：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">　　　　</span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #ff00ff">sum</span><span style="COLOR: #000000">&nbsp;(a,b,<img src="http://www.cnblogs.com/Images/dot.gif">)</span></div>
如果想取得...所代表的参数，可以在函数中访问arg局部变量（表类型）得到 (<span style="COLOR: red">lua5.1: 取消arg，并直接用"..."来代表可变参数了，本质还是arg</span>)。<br>　　　　如 sum(1,2,3,4)<br>　　　　则，在函数中，a = 1, b = 2, arg = {3, 4}&nbsp; (<span style="COLOR: red">lua5.1:&nbsp; a = 1, b = 2, ... = {3, 4}</span>)<br>　　　　更可贵的是，它可以同时返回多个结果，比如：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">　　　　</span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;s()<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　　　</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="FONT-WEIGHT: bold; COLOR: #800000">1</span><span style="COLOR: #000000">,</span><span style="FONT-WEIGHT: bold; COLOR: #800000">2</span><span style="COLOR: #000000">,</span><span style="FONT-WEIGHT: bold; COLOR: #800000">3</span><span style="COLOR: #000000">,</span><span style="FONT-WEIGHT: bold; COLOR: #800000">4</span><span style="COLOR: #000000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　a,b,c,d&nbsp;</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">&nbsp;s()&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">&nbsp;此时，a&nbsp;=&nbsp;1,&nbsp;b&nbsp;=&nbsp;2,&nbsp;c&nbsp;=&nbsp;3,&nbsp;d&nbsp;=&nbsp;4</span><span style="COLOR: #008080"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<br>　　　　前面说过，表类型可以拥有任意类型的值，包括函数！因此，有一个很强大的特性是，拥有函数的表，哦，我想更恰当的应该说是对象吧。Lua可以使用面向对象编程了。不信？举例如下：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">　　　　t&nbsp;</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　{<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　&nbsp;Age&nbsp;</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">&nbsp;</span><span style="FONT-WEIGHT: bold; COLOR: #800000">27</span><span style="COLOR: #000000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　&nbsp;</span><span style="COLOR: #0000ff">add</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">(self,&nbsp;n)&nbsp;self.Age&nbsp;</span><span style="COLOR: #808080">=</span><span style="COLOR: #000000">&nbsp;self.Age</span><span style="COLOR: #808080">+</span><span style="COLOR: #000000">n&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　}<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">(t.Age)&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">&nbsp;27</span><span style="COLOR: #008080"><br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">　　　　t.</span><span style="COLOR: #0000ff">add</span><span style="COLOR: #000000">(t,&nbsp;</span><span style="FONT-WEIGHT: bold; COLOR: #800000">10</span><span style="COLOR: #000000">)<br><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>　　　　</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">(t.Age)&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">&nbsp;37</span></div>
<br>　　　　不过，t.add(t,10) 这一句实在是有点土对吧？没关系，在Lua中，我们可以简写成：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">　　　　t:</span><span style="COLOR: #0000ff">add</span><span style="COLOR: #000000">(</span><span style="FONT-WEIGHT: bold; COLOR: #800000">10</span><span style="COLOR: #000000">)&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008080">--</span><span style="COLOR: #008080">&nbsp;相当于&nbsp;t.add(t,10)</span></div>
<br>　　G.&nbsp; Userdata 和 Thread<br>　　　　这两个类型的话题，超出了本文的内容，就不打算细说了。<br><br>VI.&nbsp; 结束语<br>　　就这么结束了吗？当然不是，接下来，我们需要用Lua解释器，来帮助理解和实践了。相信这样会更快的对Lua上手了。<br>　　就象C语言一样，Lua提供了相当多的标准函数来增强语言的功能。使用这些标准函数，可以很方便的操作各种数据类型，并处理输入输出。有关这方面的信息，我们可以参考《Programming in Lua 》一书，也可以在网络上直接观看电子版，网址为：<a href="http://www.lua.org/pil/index.html"><font color=#000000>http://www.lua.org/pil/index.html</font></a><br>　　<br>备注：本文的部份内容摘、译自lua随机文档。<br>相关链接：<br>1. Lua 官方网站： <a href="http://www.lua.org/"><font color=#000000>http://www.lua.org</font></a> <br>2. Lua Wiki网站，你可以在这里找到很多相关的资料，如文档、教程、扩展，以及C/C++的包装等： <a href="http://lua-users.org/wiki/"><font color=#000000>http://lua-users.org/wiki/</font></a><br>3. Lua 打包下载（包括各种平台和编译器的工程文件如vs2003,vs2005）：http://luabinaries.luaforge.net/download.html<br><br>这是我编译好的Lua5.02的解释器：<a href="http://files.cnblogs.com/ly4cn/lua.zip"><font color=#000000>http://files.cnblogs.com/ly4cn/lua.zip</font></a><br>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113190.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 22:55 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113190.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lua 脚本 C++ 封装库 LuaWrapper </title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113186.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 14:46:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113186.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113186.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113186.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113186.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113186.html</trackback:ping><description><![CDATA[<div class=postText>
<p>转载： <a href="http://www.d2-life.com/LBS/blogview.asp?logID=41"><font color=#56662d>http://www.d2-life.com/LBS/blogview.asp?logID=41</font></a></p>
<p><font color=#56662d></font></p>
<p>　　使用Lua作脚本，主要是因为它小巧玲珑（体积小，运行快），而且它的语法又比较简单明了。不过，使用LuaAPI将Lua引擎集成到程序中，确实有一些不方便——用落木随风网友的话来说，就是"就象用汇编"。当然，现在你不用再这么辛苦了，因为你可以使用LuaWrapper For C++。使用这个工具，在C++中集成Lua脚本就是轻而易举的事。你原有的C++函数和类，几乎不需要任何改变，就可以与Lua脚本共享。<br></p>
<p>作者： 沐枫 （第二人生成员）<br>版权所有转载请注明原出处<br>主页：第二人生 <a href="http://www.d2-life.com/" target=_blank rel=nofollow><font color=#56662d>http://www.d2-life.com</font></a><br>　　　<a href="http://www.d2-life.com/LBS/blogview.asp?logID=41" target=_blank rel=nofollow><font color=#56662d>http://www.d2-life.com/LBS/blogview.asp?logID=41</font></a><br><br>为什么要用Lua作脚本？<br>　　使用Lua作脚本，主要是因为它小巧玲珑（体积小，运行快），而且它的语法又比较简单明了。不过，使用LuaAPI将Lua引擎集成到程序中，确实有一些不方便——用落木随风网友的话来说，就是"就象用汇编"。当然，现在你不用再这么辛苦了，因为你可以使用LuaWrapper For C++。使用这个工具，在C++中集成Lua脚本就是轻而易举的事。你原有的C++函数和类，几乎不需要任何改变，就可以与Lua脚本共享。<br>　　我们接下来，用实例来说明，如何用LuaWrapper来集成Lua脚本到你的程序中去。<br><br>1.&nbsp;&nbsp;创建Lua引擎<br>　　LuaWrap lua; 或者 LuaWrap* lua = new LuaWrap;<br>　　创建一个LuaWrap对象，就是创建一个Lua脚本引擎。并且根据Lua的特性，你可以创建任意多个Lua引擎，甚至可以分布在不同的线程当中。<br><br>2.&nbsp;&nbsp;装载并执行脚本程序<br>　　你可以从缓冲区中装载Lua脚本：<br>　　lua.LoadString(<br>　　　　"print('Hello World')"<br>　　);<br>　　当然，你也可以从文件中装入，并执行Lua脚本：<br>　　Lua.LoadFile("./test.lua");<br>　　Lua的脚本，可以是源代码，也可以经过编译后的中间代码。也许你对编译后的中间代码更感兴趣——如果你不希望让源代码赤裸裸的袒露在大家的眼前。<br><br>3.&nbsp;&nbsp;获取和设置Lua变量<br>　　能够获取和设置脚本变量的内容，是一个最基本的功能。你可以使用GetGlobal和SetGlobal函数来做到这一点：<br>　　(1)&nbsp;&nbsp;获取变量：<br>　　　　int a = lua.GetGlobal&lt;int&gt;("a");<br>　　　　LuaTable table = lua.GetGlobal&lt;LuaTable&gt;("t");<br>　　　　这里，&lt;&gt; 里头的类型，就是想要的变量的类型。<br>　　(2)&nbsp;&nbsp;设置变量：<br>　　　　lua.SetGlobal("a", a); <br>　　　　lua.SetGlobal("t", table);<br><br>4.&nbsp;&nbsp;调用Lua函数<br>　　使用Call函数，就可以很简单的从你的程序中调用Lua函数：<br>　　lua.Call&lt;void&gt;("print", "Hello World");<br>　　int sum = lua.Call&lt;int&gt;("add", 2, 3);<br>　　这里，&lt;&gt; 里头的类型是返回值的类型。<br><br>5.&nbsp;&nbsp;如何让Lua也能调用C++的函数<br>　　精采的地方来了。假如有下面这样的一个函数：<br>　　int add(int a, int b)<br>　　{<br>　　　　return a + b;<br>　　}<br>　　如果想让它能够让Lua使用，只需将它注册到Lua引擎当中就可以了：<br>　　lua.RegisterFunc("add", int(int,int), add);<br>　　这样，Lua中就可以用直接使用了：<br>　　（Lua脚本）sum = add(1, 3) <br><br>　　(*) RegisterFunc的功能，就是让你把C++的函数注册到Lua中，供Lua脚本使用。<br>　　　　第一个参数，是想要在Lua中用的函数名。<br>　　　　第二个参数，是C++中函数的原型； C++允许函数重载的，你可以使用函数原型，来选择需要注册到Lua引擎中的那个函数。<br>　　　　第三个参数，就是C++中函数的指针了。<br><br>6.&nbsp;&nbsp;如何能让C++的类在Lua中使用<br>　　我们先看看下面这个C++类：<br>class MyArray<br>{<br>&nbsp;&nbsp;std::vector&lt;double&gt; array;<br>public:<br>&nbsp;&nbsp;void setvalue(int index, double value);<br>&nbsp;&nbsp;double getvalue(int index);<br>&nbsp;&nbsp;int size();<br>&nbsp;&nbsp;const char* ToString();<br>};<br><br>　　你准备要让Lua能够自由访问并操作这个类。很简单，你只需增加几个宏定义就可以了：<br><br>class MyArray<br>{<br>&nbsp;&nbsp;std::vector&lt;double&gt; array;<br>public:<br>&nbsp;&nbsp;void setvalue(int index, double value);<br>&nbsp;&nbsp;double getvalue(int index);<br>&nbsp;&nbsp;int size();<br>&nbsp;&nbsp;const char* ToString();<br>&nbsp;&nbsp;// 将一个 class 作为一个 Lua 对象是很容易的，只需要增加以下宏定义。<br>&nbsp;&nbsp;DEFINE_TYPENAME("My.array");<br>&nbsp;&nbsp;BEGIN_REGLUALIB("array")<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LUALIB_ITEM_CREATE("new", MyArray )&nbsp;&nbsp;// 创建MyArray&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LUALIB_ITEM_DESTROY("del", MyArray )&nbsp;&nbsp;// 消除MyArray。<br>&nbsp;&nbsp;END_REGLUALIB()<br>&nbsp;&nbsp;BEGIN_REGLUALIB_MEMBER()<br>&nbsp;&nbsp;&nbsp;&nbsp;LUALIB_ITEM_FUNC("size", int (MyArray*), &amp;MyArray::size)<br>&nbsp;&nbsp;&nbsp;&nbsp;LUALIB_ITEM_FUNC("__getindex", double(MyArray*, int), &amp;MyArray::getvalue)&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;LUALIB_ITEM_FUNC("__newindex", void (MyArray*, int, double), &amp;MyArray::setvalue)<br>&nbsp;&nbsp;&nbsp;&nbsp;LUALIB_ITEM_FUNC("__tostring", const char* (MyArray*), &amp;MyArray::ToString)<br>&nbsp;&nbsp;&nbsp;&nbsp;LUALIB_ITEM_DESTROY("__gc", MyArray ) &nbsp;&nbsp;// 垃圾收集时消除对象用。<br>&nbsp;&nbsp;END_REGLUALIB_MEMBER()<br>};<br><br>　　只要有了这些宏定义，这个类就是可以在Lua中使用的类了，我们就可以在Lua中注册这个类了：<br>　　lua.Register&lt;MyArray&gt;()<br><br>　　这样注册以后，我们在Lua中就可以使用这个类了：<br>　　a = array.new()&nbsp;&nbsp;-- 创建对象，相当于 a = new Myarray<br>　　a[1] = 10&nbsp;&nbsp;-- 调用__newindex，也就是C++中的 a-&gt;setvalue(1, 10)<br>　　a[2] = 20&nbsp;&nbsp;-- 调用__newindex，也就是C++中的 a-&gt;setvalue(2, 20)<br>　　print(<br>　　　　a,&nbsp;&nbsp;-- 调用 __tostring，也就是C++中的 a-&gt;ToString()<br>　　　　a:size(), -- 相当于C++中的 a-&gt;size()<br>　　　　a[1], -- 调用__getindex，也就是C++中的a-&gt;getvalue(1)<br>　　　　a[2]) --调用__getindex，也就是C++中的a-&gt;getvalue(2)<br>　　array.del(a)&nbsp;&nbsp;-- 清除对象，相当于 delete a<br>　　a = nil&nbsp;&nbsp;-- 清空 a，很象C++中的 a = NULL<br><br>　　当然，你也可以不用del这个对象，而是等待Lua帮你自动进行垃圾回收。在Lua进行垃圾回收时，它会自动调用这个对象的 __gc ，相当于 delete。<br><br>　　那么，在C++中要创建MyArray对象，并且传递给Lua全局变量怎么办？就象前面讲过的一样，使用SetGlobal：<br>　　MyArray* a = new MyArray; <br>　　lua.SetGlobal("a", a);<br>　　要获取该对象，同样的，应该使用GetGlobal：<br>　　MyArray* a = lua.GetGlobal&lt;MyArray&gt;("a");<br>　　<br>　　对于传递给Lua的对象，就让Lua来管理该对象的生存周期好了。如果你非要删除它的话，你可以使用DelGlobalObject：<br>　　lua.DelGlobalObject&lt;MyArray&gt;("a");<br>　　不过这么做的话，你应当明白你在做什么，因为在Lua的脚本中，可能已经在多处引用了这个对象了。删除了其中一个，将导致其它引用对象失效，从而可能引致系统崩溃。<br><br>　　(1)&nbsp;&nbsp;DEFINE_TYPENAME("My.array");<br>　　　　定义类型的名称。在Lua中，这个类型名称是唯一用来识别C++类型的，你必须为不同的对象给予不同的名称。<br><br>　　(2)&nbsp;&nbsp;BEGIN_REGLUALIB("array") ... END_REGLUALIB()<br>　　　　你可以为一个对象定义一个程序库，"array"就是程序库的名字。在程序库中定义的函数是全局函数，在Lua中，使用该函数，需要在函数前加上库的名字，如：array.new（）。通常，程序库会包含创建对象的方法。如：<br>　　　　LUALIB_ITEM_CREATE("new", MyArray )&nbsp;&nbsp;// 创建MyArray </p>
<p>　　　　这样子，你才能在Lua中创建MyArray：<br>　　　　a = array.new()<br>　　<br>　　　　你也可以选择增加一个删除对象操作：<br>　　　　LUALIB_ITEM_DESTROY("del", MyArray ) &nbsp;&nbsp;// 删除MyArray<br>　　　　这样，你就可以直接删除一个对象了：<br>　　　　array.del(a)<br><br>　　(3)&nbsp;&nbsp;BEGIN_REGLUALIB_MEMBER() ...END_REGLUALIB_MEMBER()<br>　　　　在此处，你可以定义对象的成员函数，也可以重载对象的操作符——是的，就象C++的operator重载。例如：<br>　　　　LUALIB_ITEM_FUNC("__newindex", void (MyArray*, int, double), &amp;MyArray::setvalue)<br>　　　　就是重载 operator[] 操作符。Lua中可重载的操作符还有许多，如：<br><br>　　　　__getindex：操作符[]，支持读取访问，如 v = a[10]<br>　　　　__newindex：操作符[]，支持赋值访问，如 a[10] = 1.22<br>　　　　__tostring：将变量转换成字串__add：等同于operator +<br>　　　　__add：操作符 ＋<br>　　　　__sub：操作符 -<br>　　　　__mul：操作符 &#215;<br>　　　　__div：操作符 &#247;<br>　　　　__pow：操作符 ^ (乘方)<br>　　　　__unm：一元操作符 -<br>　　　　__concat：操作符 .. (字符串连接)<br>　　　　__eq：操作符 == (a ~= b等价于 not a == b)<br>　　　　__lt：操作符 &lt; (a &gt; b 等价于 b &lt; a)<br>　　　　__le：操作符 &lt;= (a &gt;= b 等价于 b &lt;= a，要注意的是，如果没有定义"__le"，则Lua将会尝试将a&lt;=b 转换成 not (b &lt; a) )<br><br>　　　　__gc：在垃圾回收时调用此函数，相当于C++的析构函数。强烈建议定义此操作符，以免造成内存泄漏等情况。比如：<br>　　　　LUALIB_ITEM_DESTROY("__gc", MyArray ) &nbsp;&nbsp;// 垃圾收集时消除对象用。<br><br>　　　　(注) 这里要说明一下，在lua中，访问索引操作符是__index，不是__getindex，在luaWrapper库中，为了方便使用，将其映射为__getindex，同时，对__index的定义将会被忽略。<br><br>　　　　就这么简单。假如你已经有现成的类，而你没有修改该类的权力，如何将其加入到Lua中呢？答案就是，继承它，将把派生类加入到Lua中。<br><br>结束语<br>　　LuaWrapper 需要用到boost库的支持：boost/type_traits.hpp, boost/function.hpp, boost/bind.hpp，它使用了C++的模板部份特化，因此，C++编译器如果不支持此特性，将无法编译。目前支持此特性的编译器已经有很多。在VisualStudo产品系列中，只有VC7.1能支持此特性，因此，您如果正在使用VisualStudio，请确认你用的是VisualStudio2003。<br>　　如果你觉得 LuaWrapper For C++ 能够帮助你，我会感觉很荣幸。我很愿意将这个程序库分享给大家。顺便一提的是，如果你在使用过程中发现BUG，或是有好的建议，希望您能与我联系。你在使用过程中，请不要删除文件中的署名信息；如果你修改了程序库，请您在修改的文件中加入您的修改说明。当然，我会非常欢迎您能将修改后的程序回馈给我。我会继续优化并完善它。<br></p>
</div>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113186.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 22:46 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113186.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转贴】使用 Lua 编写可嵌入式脚本 </title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113184.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 14:44:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113184.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113184.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113184.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113184.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113184.html</trackback:ping><description><![CDATA[<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr vAlign=top>
            <td width="100%">
            <h1>使用 Lua 编写可嵌入式脚本</h1>
            <p id=subtitle>Lua 提供了高级抽象，却又没失去与硬件的关联</p>
            <img class=display-img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=1> </td>
            <td class=no-print width=192></td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr vAlign=top>
            <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10> </td>
            <td width="100%">
            <table class=no-print cellSpacing=0 cellPadding=0 width=160 align=right border=0>
                <tbody>
                    <tr>
                        <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10> </td>
                        <td>
                        <table cellSpacing=0 cellPadding=0 width=150 border=0>
                            <tbody>
                                <tr>
                                    <td class=v14-header-1-small></td>
                                </tr>
                            </tbody>
                        </table>
                        <table class=v14-gray-table-border cellSpacing=0 cellPadding=0 border=0>
                            <tbody>
                                <tr>
                                    <td class=no-padding width=150>
                                    <table cellSpacing=0 cellPadding=0 width=143 border=0>
                                        <img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8>
                                        <script language=JavaScript type=text/javascript>
                                        <!--
                                        document.write('
                                        <tr valign="top">
                                            <td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt=""/></td>
                                            <td width="16"><img src="//www.ibm.com/i/v14/icons/em.gif" height="16" width="16" vspace="3" alt="将此页作为电子邮件发送" /></td>
                                            <td width="122">
                                            <p><a class="smallplainlink" href="javascript:document.email.submit();"><strong>将此页作为电子邮件发送</strong></a></p>
                                            </td>
                                        </tr>
                                        ');
                                        //-->
                                        </script>
                                        <tbody>
                                            <tr vAlign=top>
                                                <td width=8><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></td>
                                                <td width=16><img height=16 alt=将此页作为电子邮件发送 src="http://www.ibm.com/i/v14/icons/em.gif" width=16 vspace=3></td>
                                                <td width=122>
                                                <p><a class=smallplainlink href="javascript:document.email.submit();"><strong><font color=#444444 size=2>将此页作为电子邮件发送</font></strong></a></p>
                                                </td>
                                            </tr>
                                            <tbody>
                                                <tr vAlign=top>
                                                    <td width=8><font color=#444444 size=2><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></font> </td>
                                                    <td width=16></td>
                                                    <td width=122></td>
                                                </tr>
                                                <noscript></noscript>
                                            </tbody>
                                        </table>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                            <!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- 03/20/06 updated by gretchen --><br>
                            <table cellSpacing=0 cellPadding=0 width=150 border=0>
                                <tbody>
                                    <tr>
                                        <td class=v14-header-2-small></td>
                                    </tr>
                                </tbody>
                            </table>
                            <table class=v14-gray-table-border cellSpacing=0 cellPadding=0 border=0>
                                <tbody>
                                    <tr>
                                        <td class=no-padding width=150>
                                        <table cellSpacing=0 cellPadding=0 width=143 border=0>
                                            <tbody>
                                                <tr vAlign=top>
                                                    <td width=8><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8> </td>
                                                    <td></td>
                                                    <td width=125></td>
                                                </tr>
                                            </tbody>
                                        </table>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                            <!--end RESERVED FOR FUTURE USE INCLUDE FILES--><br></td>
                        </tr>
                    </tbody>
                </table>
                <p>级别: 初级</p>
                <p><a href="http://www-128.ibm.com/developerworks/cn/linux/l-lua.html#author"><font color=#996699 size=2>Martin Streicher </font></a>(<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#109;&#97;&#114;&#116;&#105;&#110;&#46;&#115;&#116;&#114;&#101;&#105;&#99;&#104;&#101;&#114;&#64;&#108;&#105;&#110;&#117;&#120;&#45;&#109;&#97;&#103;&#46;&#99;&#111;&#109;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#20351;&#29992;&#32;&#76;&#117;&#97;&#32;&#32534;&#20889;&#21487;&#23884;&#20837;&#24335;&#33050;&#26412;"><font color=#5c81a7 size=2>martin.streicher@linux-mag.com</font></a>), 首席编辑, Linux Magazine<br></p>
                <p>2006 年 6 月 12 日</p>
                <blockquote>虽然编译性编程语言和脚本语言各自具有自己独特的优点，但是如果我们使用这两种类型的语言来编写大型的应用程序会是什么样子呢？Lua 是一种嵌入式脚本语言，它非常小，速度很快，功能却非常强大。在创建其他配置文件或资源格式（以及与之对应的解析器）之前，请尝试一下 Lua。</blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
                <p>尽管诸如 Perl、Python、PHP 和 Ruby 之类的解释性编程语言日益被 Web 应用程序广泛地采纳 —— 它们已经长期用来实现自动化系统管理任务 —— 但是诸如 C、C++ 之类的编译性编程语言依然是必需的。编译性编程语言的性能是脚本语言所无法企及的（只有手工调优的汇编程序的性能才能超过它），有些软件 —— 包括操作系统和设备驱动程序 —— 只能使用编译代码来高效地实现。实际上，当软件和硬件需要进行无缝地连接操作时，程序员本能地就会选择 C 编译器：C 非常基础，距离 &#8220;原始金属材料非常近&#8221; —— 即可以操作硬件的很多特性 —— 并且 C 的表现力非常强大，可以提供高级编程结构，例如结构、循环、命名变量和作用域。</p>
                <p>然而，脚本语言也有自己独特的优点。例如，当某种语言的解释器被成功移植到一种平台上以后，使用这种语言编写的大量脚本就可以不加任何修改在这种新平台上运行 —— 它们没有诸如系统特定的函数库之类的依赖限制。（我们可以考虑一下 Microsoft&#174; Windows&#174; 操作系统上的许多 DLL 文件和 UNIX&#174; 及 Linux&#174; 上的很多 libcs）。另外，脚本语言通常都还会提供高级编程构造和便利的操作，程序员可以使用这些功能来提高生产效率和灵活性。另外，使用解释语言来编程的程序员工作的速度更快，因为这不需要编译和链接的步骤。C 及其类似语言中的 &#8220;编码、编译、链接、运行&#8221; 周期缩减成了更为紧凑的 &#8220;编写脚本、运行&#8221;。</p>
                <p><a name=luanovel><span class=atitle><font face=Arial size=4>Lua 新特性</font><font size=2> </font></span></a></p>
                <p>与其他脚本语言一样，Lua 也有自己的一些特性：</p>
                <ul>
                    <li><strong>Lua 类型。</strong>在 Lua 中，值可以有类型，但是变量的类型都是动态决定的。<em>nil、布尔型、数字</em> 和 <em>字符串</em> 类型的工作方式与我们期望的一样。
                    <ul>
                        <li>Nil 是值为 <code>nil</code> 的一种特殊类型，用来表示没有值。
                        <li>布尔型的值可以是 <code>true</code> 和 <code>false</code> 常量。（<code>Nil</code> 也可以表示 false，任何非 <code>nil</code> 的值都表示 true。）
                        <li>Lua 中所有的数字都是双精度的（不过我们可以非常简便地编写一些代码来实现其他数字类型）。
                        <li>字符串是定长字符数组。（因此，要在一个字符串后面附加上字符，必须对其进行拷贝。） </li>
                    </ul>
                    <li><em>表、函数</em> 和<em>线程</em> 类型都是引用。每个都可以赋值给一个变量，作为参数传递，或作为返回值从函数中返回。例如，下面是一个存储函数的例子：<br><br>
                    <table cellSpacing=0 cellPadding=5 width="80%" bgColor=#eeeeee border=1>
                        <tbody>
                            <tr>
                                <td><code>
                                <pre class=section>-- example of an anonymous function
                                -- returned as a value
                                -- see http://www.tecgraf.puc-rio.br/~lhf/ftp/doc/hopl.pdf
                                function add(x)
                                return function (y) return (x + y) end
                                end
                                f = add(2)
                                print(type(f), f(10))
                                function  12
                                </pre>
                                </code></td>
                            </tr>
                        </tbody>
                    </table>
                    <br>
                    <li><strong>Lua 线程。</strong>线程是通过调用内嵌函数 <code>coroutine.create(f)</code> 创建的一个<em>协同例程 (co-routine)</em>，其中 <em>f</em> 是一个 Lua 函数。线程不会在创建时启动；相反，它是在创建之后使用 <code>coroutine.resume(t)</code> 启动的，其中 <em>t</em> 就是一个线程。每个协同例程都必须使用 <code>coroutine.yield()</code> 偶尔获得其他协同例程的处理器。
                    <li><strong>赋值语句。</strong>Lua 允许使用多种赋值语句，可以先对表达式进行求值，然后再进行赋值。例如，下面的语句：<br><br>
                    <table cellSpacing=0 cellPadding=5 width="80%" bgColor=#eeeeee border=1>
                        <tbody>
                            <tr>
                                <td><code>
                                <pre class=section>i = 3
                                a = {1, 3, 5, 7, 9}
                                i, a[i], a[i+1], b = i+1, a[i+1], a[i]
                                print (i, a[3], a[4], b, I)
                                </pre>
                                </code></td>
                            </tr>
                        </tbody>
                    </table>
                    <br>会生成 <code>4 7 5 nil nil</code>。如果变量列表的个数大于值列表的个数，那么多出的变量都被赋值为 <code>nil</code>；因此，<code>b</code> 就是 nil。如果值的个数多于变量的个数，那么多出的值部分就会简单地丢弃。在 Lua 中，变量名是大小写敏感的，这可以解释为什么 <code>I</code> 的值是 nil。
                    <li><strong>块（Chunk）。</strong> <em>块</em> 可以是任何 Lua 语句序列。块可以保存到文件中，或者保存到 Lua 程序中的字符串中。每个块都是作为一个匿名函数体来执行的。因此，块可以定义局部变量和返回值。
                    <li><strong>更酷的东西。</strong>Lua 具有一个标记-清理垃圾收集器。在 Lua 5.1 中，垃圾收集器是以增量方式工作的。Lua 具有完整的词法闭包（这与 Scheme 类似，而与 Python 不同）。Lua 具有可靠的尾部调用语义（同样，这也与 Scheme 类似，而与 Python 不同）。 </li>
                </ul>
                <p>在 <em>Programming in Lua</em> 和 Lua-users wiki （链接请参见后面的 <a href="http://www-128.ibm.com/developerworks/cn/linux/l-lua.html#resources"><font color=#996699 size=2>参考资料</font></a> 部分）中可以找到更多 Lua 代码的例子。</p>
                <p>在所有的工程任务中，要在编译性语言和解释性语言之间作出选择，就意味着要在这种环境中对每种语言的优缺点、权重和折中进行评测，并接受所带来的风险。</p>
                <br>
                <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                    <tbody>
                        <tr>
                            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"> <br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0> </td>
                        </tr>
                    </tbody>
                </table>
                <table class=no-print cellSpacing=0 cellPadding=0 align=right>
                    <tbody>
                        <tr align=right>
                            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"> <br>
                            <table cellSpacing=0 cellPadding=0 border=0>
                                <tbody>
                                    <tr>
                                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0> <br></td>
                                        <td vAlign=top align=right><a class=fbox href="http://www-128.ibm.com/developerworks/cn/linux/l-lua.html#main"><strong><font size=2><font color=#996699>回页首</font><font color=#444444> </font></font></strong></a></td>
                                    </tr>
                                </tbody>
                            </table>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <br><br>
                <p><a name=N100ED><span class=atitle><font face=Arial size=4>在两个世界之间最好地进行混合</font><font size=2> </font></span></a></p>
                <p>如果您希望充分利用这两个世界的优点，应该怎样办呢，是选择最好的性能还是选择高级强大的抽象？更进一步说，如果我们希望对处理器密集且依赖于系统的算法和函数以及与系统无关且很容易根据需要而进行修改的单独逻辑进行优化，那又当如何呢？</p>
                <p>对高性能代码和高级编程的需要进行平衡是 Lua（一种可嵌入式脚本语言）要解决的问题。在需要时我们可以使用编译后的代码来实现底层的功能，然后调用 Lua 脚本来操作复杂的数据。由于 Lua 脚本是与编译代码独立的，因此我们可以单独修改这些脚本。使用 Lua，开发周期就非常类似于 &#8220;编码、编译、运行、编写脚本、编写脚本、编写脚本 ...&#8221;。</p>
                <p>例如，Lua Web 站点 &#8220;使用&#8221; 页面（请参见 <a href="http://www-128.ibm.com/developerworks/cn/linux/l-lua.html#resources"><font color=#996699 size=2>参考资料</font></a>）列出了主流市场上的几个计算机游戏，包括 <em>World of Warcraft</em> 和（家用版的）<em>Defender</em>，它们集成 Lua 来实现很多东西，从用户界面到敌人的人工智能都可以。Lua 的其他应用程序包括流行的 Linux 软件更新工具 apt-rpm 的扩展机制，还有 &#8220;Crazy Ivan&#8221; Robocup 2000 冠军联赛的控制逻辑。这个页面上的很多推荐感言都对 Lua 的小巧与杰出性能赞不绝口。</p>
                <br>
                <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                    <tbody>
                        <tr>
                            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"> <br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0> </td>
                        </tr>
                    </tbody>
                </table>
                <table class=no-print cellSpacing=0 cellPadding=0 align=right>
                    <tbody>
                        <tr align=right>
                            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"> <br>
                            <table cellSpacing=0 cellPadding=0 border=0>
                                <tbody>
                                    <tr>
                                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0> <br></td>
                                        <td vAlign=top align=right><a class=fbox href="http://www-128.ibm.com/developerworks/cn/linux/l-lua.html#main"><strong><font size=2><font color=#996699>回页首</font><font color=#444444> </font></font></strong></a></td>
                                    </tr>
                                </tbody>
                            </table>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <br><br>
                <p><a name=N10106><span class=atitle><font face=Arial size=4>开始使用 Lua</font><font size=2> </font></span></a></p>
                <p>Lua 5.0.2 版本是撰写本文时的最新版本，不过最近刚刚发布了 5.1 版本。您可以从 lua.org 上下载 Lua 的源代码，在 Lua-users wiki（链接请参见 <a href="http://www-128.ibm.com/developerworks/cn/linux/l-lua.html#resources"><font color=#996699 size=2>参考资料</font></a>）上可以找到预先编译好的二进制文件。完整的 Lua 5.0.2 核心文件中包括了标准库和 Lua 编译器，不过只有 200KB 大小。</p>
                <p>如果您使用的是 Debian Linux，那么可以以超级用户的身份运行下面的命令来快速安装 Lua 5.0：</p>
                <table cellSpacing=0 cellPadding=5 width="80%" bgColor=#eeeeee border=1>
                    <tbody>
                        <tr>
                            <td><code>
                            <pre class=section># apt-get install lua50
                            </pre>
                            </code></td>
                        </tr>
                    </tbody>
                </table>
                <br>
                <p>本文中给出的例子都是在 Debian Linux Sarge 上运行的，使用的是 Lua 5.0.2 和 2.4.27-2-686 版本的 Linux 内核。</p>
                <p>在系统上安装好 Lua 之后，我们可以首先来试用一下单独的 Lua 解释器。（所有的 Lua 应用程序必须要嵌入到宿主应用程序中。解释器只是一种特殊类型的宿主，对于开发和调试工作来说非常有用。）创建一个名为 factorial.lua 的文件，然后输入下面的代码：</p>
                <table cellSpacing=0 cellPadding=5 width="80%" bgColor=#eeeeee border=1>
                    <tbody>
                        <tr>
                            <td><code>
                            <pre class=section>-- defines a factorial function
                            function fact (n)
                            if n == 0 then
                            return 1
                            else
                            return n * fact(n-1)
                            end
                            end
                            print("enter a number:")
                            a = io.read("*number")
                            print(fact(a))
                            </pre>
                            </code></td>
                        </tr>
                    </tbody>
                </table>
                <br>
                <p>factorial.lua 中的代码 —— 更确切地说是任何 Lua 语句序列 —— 都称为一个<em>块</em>，这在上面的 <a href="http://www-128.ibm.com/developerworks/cn/linux/l-lua.html#luanovel"><font color=#996699 size=2>Lua 特性</font></a> 中已经进行了介绍。要执行刚才创建的代码块，请运行命令 <code>lua factorial.lua</code>：</p>
                <table cellSpacing=0 cellPadding=5 width="80%" bgColor=#eeeeee border=1>
                    <tbody>
                        <tr>
                            <td><code>
                            <pre class=section>$ lua factorial.lua
                            enter a number:
                            10
                            3628800
                            </pre>
                            </code></td>
                        </tr>
                    </tbody>
                </table>
                <br>
                <p>或者像在其他解释性语言中一样，我们可以在代码顶部添加一行 &#8220;标识符&#8221;（<code>#!</code>），使这个脚本变成可执行的，然后像单独命令一样来运行这个文件：</p>
                <table cellSpacing=0 cellPadding=5 width="80%" bgColor=#eeeeee border=1>
                    <tbody>
                        <tr>
                            <td><code>
                            <pre class=section>$ (echo '#! /usr/bin/lua'; cat factorial.lua) &gt; factorial
                            $ chmod u+x factorial
                            $ ./factorial
                            enter a number:
                            4
                            24
                            </pre>
                            </code></td>
                        </tr>
                    </tbody>
                </table>
                <br><br>
                <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                    <tbody>
                        <tr>
                            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"> <br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0> </td>
                        </tr>
                    </tbody>
                </table>
                <table class=no-print cellSpacing=0 cellPadding=0 align=right>
                    <tbody>
                        <tr align=right>
                            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"> <br>
                            <table cellSpacing=0 cellPadding=0 border=0>
                                <tbody>
                                    <tr>
                                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0> <br></td>
                                        <td vAlign=top align=right><a class=fbox href="http://www-128.ibm.com/developerworks/cn/linux/l-lua.html#main"><strong><font size=2><font color=#996699>回页首</font><font color=#444444> </font></font></strong></a></td>
                                    </tr>
                                </tbody>
                            </table>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <br><br>
                <p><a name=N1015A><span class=atitle><font face=Arial size=4>Lua 语言</font><font size=2> </font></span></a></p>
                <p>Lua 具有现代脚本语言中的很多便利：作用域，控制结构，迭代器，以及一组用来处理字符串、产生及收集数据和执行数学计算操作的标准库。在 <em>Lua 5.0 Reference Manual</em> 中有对 Lua 语言的完整介绍（请参见 <a href="http://www-128.ibm.com/developerworks/cn/linux/l-lua.html#resources"><font color=#996699 size=2>参考资料</font></a>）。</p>
                <p>在 Lua 中，只有<em>值</em> 具有类型，而变量的类型是动态决定的。Lua 中的基本类型（值）有 8 种： <em>nil，布尔型，数字，字符串，函数，线程，表</em> 以及 <em>用户数据</em>。前 6 种类型基本上是自描述的（例外情况请参见上面的 <a href="http://www-128.ibm.com/developerworks/cn/linux/l-lua.html#luanovel"><font color=#996699 size=2>Lua 特性</font></a> 一节）；最后两个需要一点解释。</p>
                <p><a name=N1017A><span class=smalltitle><strong><font size=2><font face=Arial>Lua 表</font> </font></strong></span></a></p>
                <p>在 Lua 中，表是用来保存所有数据的结构。实际上，表是 Lua 中<em>惟一的</em> 数据结构。我们可以将表作为数组、字典（也称为<em>散列</em> 或<em>联合数组</em>）、树、记录，等等。</p>
                <p>与其他编程语言不同，Lua 表的概念不需要是异构的：表可以包含任何类型的组合，也可以包含类数组元素和类字典元素的混合体。另外，<em>任何</em> Lua 值 —— 包括函数或其他表 —— 都可以用作字典元素的键值。</p>
                <p>要对表进行浏览，请启动 Lua 解释器，并输入清单 1 中的<strong>黑体</strong>显示的代码。</p>
                <br><a name=Listing1><font size=2><strong>清单 1. 体验 Lua 表</strong> </font></a><br>
                <table cellSpacing=0 cellPadding=5 width="100%" bgColor=#eeeeee border=1>
                    <tbody>
                        <tr>
                            <td><code>
                            <pre class=section>$ lua
                            &gt; -- create an empty table and add some elements
                            &gt; t1 = {}
                            &gt; t1[1] = "moustache"
                            &gt; t1[2] = 3
                            &gt; t1["brothers"] = true
                            &gt; -- more commonly, create the table and define elements
                            &gt; all at once
                            &gt; t2 = {[1] = "groucho", [3] = "chico", [5] = "harpo"}
                            &gt; t3 = {[t1[1]] = t2[1], accent = t2[3], horn = t2[5]}
                            &gt; t4 = {}
                            &gt; t4[t3] = "the marx brothers"
                            &gt; t5 = {characters = t2, marks = t3}
                            &gt; t6 = {["a night at the opera"] = "classic"}
                            &gt; -- make a reference and a string
                            &gt; i = t3
                            &gt; s = "a night at the opera"
                            &gt; -- indices can be any Lua value
                            &gt; print(t1[1], t4[t3], t6[s])
                            moustache   the marx brothers classic
                            &gt; -- the phrase table.string is the same as table["string"]
                            &gt; print(t3.horn, t3["horn"])
                            harpo   harpo
                            &gt; -- indices can also be "multi-dimensional"
                            &gt; print (t5["marks"]["horn"], t5.marks.horn)
                            harpo   harpo
                            &gt; -- i points to the same table as t3
                            &gt; = t4[i]
                            the marx brothers
                            &gt; -- non-existent indices return nil values
                            &gt; print(t1[2], t2[2], t5.films)
                            nil     nil     nil
                            &gt;  -- even a function can be a key
                            &gt; t = {}
                            &gt; function t.add(i,j)
                            &gt;&gt; return(i+j)
                            &gt;&gt; end
                            &gt; print(t.add(1,2))
                            3
                            &gt; print(t['add'](1,2))
                            3
                            &gt;  -- and another variation of a function as a key
                            &gt; t = {}
                            &gt; function v(x)
                            &gt;&gt; print(x)
                            &gt;&gt; end
                            &gt; t[v] = "The Big Store"
                            &gt; for key,value in t do key(value) end
                            The Big Store
                            </pre>
                            </code></td>
                        </tr>
                    </tbody>
                </table>
                <br>
                <p>正如我们可能期望的一样，Lua 还提供了很多迭代器函数来对表进行处理。全局变量 <code>table</code> 提供了这些函数（是的，Lua 包就是表）。有些函数，例如 <code>table.foreachi()</code>，会期望一个从 1（数字 1）开始的连续整数范围：</p>
                <table cellSpacing=0 cellPadding=5 width="80%" bgColor=#eeeeee border=1>
                    <tbody>
                        <tr>
                            <td><code>
                            <pre class=section>&gt; table.foreachi(t1, print)
                            1 moustache
                            2 3
                            </pre>
                            </code></td>
                        </tr>
                    </tbody>
                </table>
                <br>
                <p>另外一些函数，例如 <code>table.foreach()</code>，会对整个表进行迭代：</p>
                <table cellSpacing=0 cellPadding=5 width="80%" bgColor=#eeeeee border=1>
                    <tbody>
                        <tr>
                            <td><code>
                            <pre class=section>&gt; table.foreach(t2,print)
                            1       groucho
                            3       chico
                            5       harpo
                            &gt; table.foreach(t1,print)
                            1       moustache
                            2       3
                            brothers        true
                            </pre>
                            </code></td>
                        </tr>
                    </tbody>
                </table>
                <br>
                <p>尽管有些迭代器对整数索引进行了优化，但是所有迭代器都只简单地处理 (key, value) 对。</p>
                <p>现在我们可以创建一个表 <code>t</code>，其元素是 <code>{2, 4, 6, language="Lua", version="5", 8, 10, 12, web="www.lua.org"}</code>，然后运行 <code>table.foreach(t, print) </code>和 <code>table.foreachi(t, print)</code>。</p>
                <p><a name=N10233><span class=smalltitle><strong><font size=2><font face=Arial>用户数据</font> </font></strong></span></a></p>
                <p>由于 Lua 是为了嵌入到使用另外一种语言（例如 C 或 C++）编写的宿主应用程序中，并与宿主应用程序协同工作，因此数据可以在 C 环境和 Lua 之间进行共享。正如 <em>Lua 5.0 Reference Manual</em> 所说，<code>userdata</code> 类型允许我们在 Lua 变量中保存任意的 C 数据。我们可以认为 <code>userdata</code> 就是一个字节数组 —— 字节可以表示指针、结构或宿主应用程序中的文件。</p>
                <p>用户数据的内容源自于 C，因此在 Lua 中不能对其进行修改。当然，由于用户数据源自于 C，因此在 Lua 中也没有对用户数据预定义操作。不过我们可以使用另外一种 Lua 机制来创建对 <code>userdata</code> 进行处理的操作，这种机制称为 <em>元表（metatable）。</em></p>
                <p><a name=N10251><span class=smalltitle><strong><font size=2><font face=Arial>元表</font> </font></strong></span></a></p>
                <p>由于表和用户数据都非常灵活，因此 Lua 允许我们重载这两种类型的数据的操作（不能重载其他 6 种类型）。<em>元表</em> 是一个（普通的）Lua 表，它将标准操作映射成我们提供的函数。元表的键值称为<em>事件</em>；值（换而言之就是函数）称为<em>元方法</em>。</p>
                <p>函数 <code>setmetatable()</code> 和 <code>getmetatable()</code> 分别对对象的元表进行修改和查询。每个表和 <code>userdada</code> 对象都可以具有自己的元表。</p>
                <p>例如，添加操作对应的事件是 <code>__add</code>。我们可以推断这段代码所做的事情么？</p>
                <table cellSpacing=0 cellPadding=5 width="80%" bgColor=#eeeeee border=1>
                    <tbody>
                        <tr>
                            <td><code>
                            <pre class=section>-- Overload the add operation
                            -- to do string concatenation
                            --
                            mt = {}
                            function String(string)
                            return setmetatable({value = string or ''}, mt)
                            end
                            -- The first operand is a String table
                            -- The second operand is a string
                            -- .. is the Lua concatenate operator
                            --
                            function mt.__add(a, b)
                            return String(a.value..b)
                            end
                            s = String('Hello')
                            print((s + ' There ' + ' World!').value )
                            </pre>
                            </code></td>
                        </tr>
                    </tbody>
                </table>
                <br>
                <p>这段代码会产生下面的文本：</p>
                <table cellSpacing=0 cellPadding=5 width="80%" bgColor=#eeeeee border=1>
                    <tbody>
                        <tr>
                            <td><code>
                            <pre class=section>Hello There World!
                            </pre>
                            </code></td>
                        </tr>
                    </tbody>
                </table>
                <br>
                <p>函数 <code>String()</code> 接收一个字符串 <code>string</code>，将其封装到一个表（<code>{value = s or ''}</code>）中，并将元表 <code>mt</code> 赋值给这个表。函数 <code>mt.__add()</code> 是一个元方法，它将字符串 <code>b</code> 添加到在 <code>a.value</code> 中找到的字符串后面 <code>b</code> 次。这行代码 <code>print((s + ' There ' + ' World!').value )</code> 调用这个元方法两次。</p>
                <p><code>__index</code> 是另外一个事件。<code>__index</code> 的元方法每当表中不存在键值时就会被调用。下面是一个例子，它记住 (memoize) 函数的值：</p>
                <table cellSpacing=0 cellPadding=5 width="80%" bgColor=#eeeeee border=1>
                    <tbody>
                        <tr>
                            <td><code>
                            <pre class=section>-- code courtesy of Rici Lake, rici@ricilake.net
                            function Memoize(func, t)
                            return setmetatable(
                            t or {},
                            {__index =
                            function(t, k)
                            local v = func(k);
                            t[k] = v;
                            return v;
                            end
                            }
                            )
                            end
                            COLORS = {"red", "blue", "green", "yellow", "black"}
                            color = Memoize(
                            function(node)
                            return COLORS[math.random(1, table.getn(COLORS))]
                            end
                            )
                            </pre>
                            </code></td>
                        </tr>
                    </tbody>
                </table>
                <br>
                <p>将这段代码放到 Lua 解释器中，然后输入 <code>print(color[1], color[2], color[1])</code>。您将会看到类似于 <code>blue black blue</code> 的内容。</p>
                <p>这段代码接收一个键值 <code>node</code>，查找 node 指定的颜色。如果这种颜色不存在，代码就会给 <code>node</code> 赋一个新的随机选择的颜色。否则，就返回赋给 node 的颜色。在前一种情况中，<code>__index</code> 元方法被执行一次以分配一个颜色。后一种情况比较简单，所执行的是快速散列查找。</p>
                <p>Lua 语言提供了很多其他功能强大的特性，所有这些特性都有很好的文档进行介绍。在碰到问题或希望与专家进行交谈时，请连接 Lua Users Chat Room IRC Channel（请参见 <a href="http://www-128.ibm.com/developerworks/cn/linux/l-lua.html#resources"><font color=#996699 size=2>参考资料</font></a>）获得非常热心的支持。</p>
                <br>
                <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                    <tbody>
                        <tr>
                            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"> <br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0> </td>
                        </tr>
                    </tbody>
                </table>
                <table class=no-print cellSpacing=0 cellPadding=0 align=right>
                    <tbody>
                        <tr align=right>
                            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"> <br>
                            <table cellSpacing=0 cellPadding=0 border=0>
                                <tbody>
                                    <tr>
                                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0> <br></td>
                                        <td vAlign=top align=right><a class=fbox href="http://www-128.ibm.com/developerworks/cn/linux/l-lua.html#main"><strong><font size=2><font color=#996699>回页首</font><font color=#444444> </font></font></strong></a></td>
                                    </tr>
                                </tbody>
                            </table>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <br><br>
                <p><a name=N102DF><span class=atitle><font face=Arial size=4>嵌入和扩展</font><font size=2> </font></span></a></p>
                <p>除了语法简单并且具有功能强大的表结构之外，Lua 的强大功能使其可以与宿主语言混合使用。由于 Lua 与宿主语言的关系非常密切，因此 Lua 脚本可以对宿主语言的功能进行扩充。但是这种融合是双赢的：宿主语言同时也可以对 Lua 进行扩充。举例来说，C 函数可以调用 Lua 函数，反之亦然。</p>
                <p>Lua 与宿主语言之间的这种共生关系的核心是宿主语言是一个<em>虚拟堆栈</em>。虚拟堆栈与实际堆栈类似，是一种后进先出（LIFO）的数据结构，可以用来临时存储函数参数和函数结果。要从 Lua 中调用宿主语言的函数（反之亦然），调用者会将一些值压入堆栈中，并调用目标函数；被调用的函数会弹出这些参数（当然要对类型和每个参数的值进行验证），对数据进行处理，然后将结果放入堆栈中。当控制返回给调用程序时，调用程序就可以从堆栈中提取出返回值。</p>
                <p>实际上在 Lua 中使用的所有的 C 应用程序编程接口（API）都是通过堆栈来进行操作的。堆栈可以保存 Lua 的值，不过值的类型必须是调用程序和被调用者都知道的，特别是向堆栈中压入的值和从堆栈中弹出的值更是如此（例如 <code>lua_pushnil()</code> 和 <code>lua_pushnumber()</code>。</p>
                <p>清单 2 给出了一个简单的 C 程序（节选自 <a href="http://www-128.ibm.com/developerworks/cn/linux/l-lua.html#resources"><font color=#996699 size=2>参考资料</font></a> 中 <em>Programming in Lua</em> 一书的第 24 章），它实现了一个很小但却功能完善的 Lua 解释器。</p>
                <br><a name=Listing2><font size=2><strong>清单 2. 一个简单的 Lua 解释器</strong> </font></a><br>
                <table cellSpacing=0 cellPadding=5 width="100%" bgColor=#eeeeee border=1>
                    <tbody>
                        <tr>
                            <td><code>
                            <pre class=section> 1 #include &lt;stdio.h&gt;
                            2 #include &lt;lua.h&gt;
                            3 #include &lt;lauxlib.h&gt;
                            4 #include &lt;lualib.h&gt;
                            5
                            6 int main (void) {
                            7   char buff[256];
                            8   int error;
                            9   lua_State *L = lua_open();   /* opens Lua */
                            10   luaopen_base(L);             /* opens the basic library */
                            11   luaopen_table(L);            /* opens the table library */
                            12   luaopen_io(L);               /* opens the I/O library */
                            13   luaopen_string(L);           /* opens the string lib. */
                            14   luaopen_math(L);             /* opens the math lib. */
                            15
                            16   while (fgets(buff, sizeof(buff), stdin) != NULL) {
                            17     error = luaL_loadbuffer(L, buff, strlen(buff), "line") ||
                            18             lua_pcall(L, 0, 0, 0);
                            19     if (error) {
                            20       fprintf(stderr, "%s", lua_tostring(L, -1));
                            21       lua_pop(L, 1);  /* pop error message from the stack */
                            22     }
                            23   }
                            24
                            25   lua_close(L);
                            26   return 0;
                            27 }
                            </pre>
                            </code></td>
                        </tr>
                    </tbody>
                </table>
                <br>
                <p>第 2 行到第 4 行包括了 Lua 的标准函数，几个在所有 Lua 库中都会使用的方便函数以及用来打开库的函数。第 9 行创建了一个 Lua <em>状态</em>。所有的状态最初都是空的；我们可以使用 <code>luaopen_...()</code> 将函数库添加到状态中，如第 10 行到第 14 行所示。</p>
                <p>第 17 行和 <code>luaL_loadbuffer()</code> 会从 <code>stdin</code> 中以块的形式接收输入，并对其进行编译，然后将其放入虚拟堆栈中。第 18 行从堆栈中弹出数据并执行之。如果在执行时出现了错误，就向堆栈中压入一个 Lua 字符串。第 20 行访问栈顶（栈顶的索引为 <code>-1</code>）作为 Lua 字符串，打印消息，然后从堆栈中删除该值。</p>
                <p>使用 C API，我们的应用程序也可以进入 Lua 状态来提取信息。下面的代码片段从 Lua 状态中提取两个全局变量：</p>
                <table cellSpacing=0 cellPadding=5 width="80%" bgColor=#eeeeee border=1>
                    <tbody>
                        <tr>
                            <td><code>
                            <pre class=section>..
                            if (luaL_loadfile(L, filename) || lua_pcall(L, 0, 0, 0))
                            error(L, "cannot run configuration file: %s", lua_tostring(L, -1));
                            lua_getglobal(L, "width");
                            lua_getglobal(L, "height");
                            ..
                            width = (int) lua_tonumber(L, -2);
                            height = (int) lua_tonumber(L, -1);
                            ..
                            </pre>
                            </code></td>
                        </tr>
                    </tbody>
                </table>
                <br>
                <p>请再次注意传输是通过堆栈进行的。从 C 中调用任何 Lua 函数与这段代码类似：使用 <code>lua_getglobal()</code> 来获得函数，将参数压入堆栈，调用 <code>lua_pcall()</code>，然后处理结果。如果 Lua 函数返回 <em>n</em> 个值，那么第一个值的位置在堆栈的 <em>-n</em> 处，最后一个值在堆栈中的位置是 -1。</p>
                <p>反之，在 Lua 中调用 C 函数也与之类似。如果您的操作系统支持动态加载，那么 Lua 可以根据需要来动态加载并调用函数。（在必须使用静态加载的操作系统中，可以对 Lua 引擎进行扩充，此时调用 C 函数时需要重新编译 Lua。）</p>
                <br>
                <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                    <tbody>
                        <tr>
                            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"> <br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0> </td>
                        </tr>
                    </tbody>
                </table>
                <table class=no-print cellSpacing=0 cellPadding=0 align=right>
                    <tbody>
                        <tr align=right>
                            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"> <br>
                            <table cellSpacing=0 cellPadding=0 border=0>
                                <tbody>
                                    <tr>
                                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0> <br></td>
                                        <td vAlign=top align=right><a class=fbox href="http://www-128.ibm.com/developerworks/cn/linux/l-lua.html#main"><strong><font size=2><font color=#996699>回页首</font><font color=#444444> </font></font></strong></a></td>
                                    </tr>
                                </tbody>
                            </table>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <br><br>
                <p><a name=N10341><span class=atitle><font face=Arial size=4>结束语</font><font size=2> </font></span></a></p>
                <p>Lua 是一种学习起来容易得难以置信的语言，但是它简单的语法却掩饰不了其强大的功能：这种语言支持对象（这与 Perl 类似），元表使表类型具有相当程度的可伸展性，C API 允许我们在脚本和宿主语言之间进行更好的集成和扩充。Lua 可以在 C、C++、C#、Java&#8482; 和 Python 语言中使用。</p>
                <p>在创建另外一个配置文件或资源格式（以及相应的处理程序）之前，请尝试一下 Lua。Lua 语言及其社区非常健壮，具有创新精神，随时准备好提供帮助。</p>
                <br>
                <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                    <tbody>
                        <tr>
                            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"> <br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0> </td>
                        </tr>
                    </tbody>
                </table>
                <table class=no-print cellSpacing=0 cellPadding=0 align=right>
                    <tbody>
                        <tr align=right>
                            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"> <br>
                            <table cellSpacing=0 cellPadding=0 border=0>
                                <tbody>
                                    <tr>
                                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0> <br></td>
                                        <td vAlign=top align=right><a class=fbox href="http://www-128.ibm.com/developerworks/cn/linux/l-lua.html#main"><strong><font size=2><font color=#996699>回页首</font><font color=#444444> </font></font></strong></a></td>
                                    </tr>
                                </tbody>
                            </table>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <br><br>
                <p><a name=resources><span class=atitle><font face=Arial size=4>参考资料 </font></span></a></p>
                <strong>学习</strong> <br>
                <ul>
                    <li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/linux/library/l-lua.html" target=_blank><font color=#5c81a7 size=2>英文原文</font></a>。<br><br>
                    <li><a href="http://www.lua.org/manual/5.0"><em><font size=2><font color=#5c81a7>Reference manual for Lua 5.0</font><font color=#444444> </font></font></em></a>介绍了 Lua 语言的完整知识。 <br><br>
                    <li>Roberto Ierusalimschy 所著的 <a href="http://www.lua.org/pil"><em><font color=#5c81a7 size=2>Programming in Lua</font></em></a>（Roberto Ierusalimschy，2003 年）是学习如何使用 Lua 有效地进行编码的非常有用的资源。 <br><br>
                    <li>请参阅 Lua-users wiki 中的 <a href="http://lua-users.org/wiki/TutorialDirectory"><font color=#5c81a7 size=2>library of Lua 教程</font></a>，学习如何使用 Lua 的特性。 <br><br>
                    <li>请参阅 <a href="http://www.lua.org/uses.html"><font color=#5c81a7 size=2>使用 Lua 的项目列表</font></a>。 <br><br>
                    <li>在 <a href="http://www.ibm.com/developerworks/cn/linux/"><font color=#5c81a7 size=2>developerWorks Linux 专区</font></a> 可以找到为 Linux 开发人员准备的更多资源。 <br><br>
                    <li>随时关注 <a href="http://www.ibm.com/developerworks/offers/techbriefings/?S_TACT=105AGX03&amp;S_CMP=art"><font color=#5c81a7 size=2>developerWorks 技术事件和网络广播</font></a>。 </li>
                </ul>
                <br><strong>获得产品和技术</strong> <br>
                <ul>
                    <li>下载 <a href="http://www.lua.org/ftp/lua-5.0.2.tar.gz"><font color=#5c81a7 size=2>Lua 5.0.2</font></a> 或 <a href="http://www.lua.org/ftp/lua-5.1.tar.gz"><font color=#5c81a7 size=2>Lua 5.1</font></a> 源代码，从头开始编译 Lua。 <br><br>
                    <li>在 <a href="http://lua-users.org/wiki/LuaBinaries"><font color=#5c81a7 size=2>Lua-users wiki</font></a> 上，浏览很多预先构建的、可安装的 Lua 二进制文件。 <br><br>
                    <li>在 <a href="http://www.luaforge.net/"><font color=#5c81a7 size=2>LuaForge</font></a> 上可以找到大量的代码库，包括很多语言绑定和专门的计算库。 <br><br>
                    <li><a href="http://www.ibm.com/developerworks/offers/sek/?S_TACT=105AGX03&amp;S_CMP=art"><font size=2><font color=#5c81a7>订购免费的 SEK for Linux</font><font color=#444444> </font></font></a>，这有两张 DVD，包括最新的 IBM for Linux 试用软件，包括 DB2&#174;、Lotus&#174;、Rational&#174;、Tivoli&#174; 和 WebSphere&#174;。 <br><br>
                    <li>在您的下一个开发项目中采用 <a href="http://www.ibm.com/developerworks/downloads/?S_TACT=105AGX03"><font color=#5c81a7 size=2>IBM 试用软件</font></a>，这可以从 developerWorks 直接下载。 <br><br></li>
                </ul>
                <br><strong>讨论</strong> <br>
                <ul>
                    <li>通过参与 <a href="http://www.ibm.com/developerworks/blogs/"><font color=#5c81a7 size=2>developerWorks blogs</font></a> 加入 developerWorks 社区。 <br><br></li>
                </ul>
                <br>
                <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                    <tbody>
                        <tr>
                            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"> <br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0> </td>
                        </tr>
                    </tbody>
                </table>
                <table class=no-print cellSpacing=0 cellPadding=0 align=right>
                    <tbody>
                        <tr align=right>
                            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"> <br>
                            <table cellSpacing=0 cellPadding=0 border=0>
                                <tbody>
                                    <tr>
                                        <td vAlign=center><br></td>
                                        <td vAlign=top align=right></td>
                                    </tr>
                                </tbody>
                            </table>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <br><br>
                <p><a name=author><span class=atitle><font face=Arial size=4>关于作者</font><font size=2> </font></span></a></p>
                <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                    <tbody>
                        <tr>
                            <td colSpan=3><font face=Arial size=4><font size=2><img height=5 alt="" src="http://www.ibm.com/i/c.gif" width="100%"></font> </font></td>
                        </tr>
                        <tr vAlign=top align=left>
                            <td>
                            <p><font face=Arial size=4></font></p>
                            </td>
                            <td><font face=Arial size=4><img height=5 alt="" src="http://www.ibm.com/i/c.gif" width=4> </font></td>
                            <td width="100%">
                            <p>Martin Streicher 是 <em>Linux Magazine</em> 的首席编辑。他在普渡大学获得了计算机硕士学位，自 1982 年以来，就一直在使用 Pascal、C、Perl、Java 以及（最近使用的）Ruby 编程语言编写类 Unix 系统。</p>
                            </td>
                        </tr>
                    </tbody>
                </table>
                </td>
            </tr>
        </tbody>
    </table>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113184.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 22:44 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113184.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转贴】如何在C++中集成Lua脚本(LuaPlus篇) </title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113183.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 14:42:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113183.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113183.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113183.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113183.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113183.html</trackback:ping><description><![CDATA[<div class=imagefix id=blog>
<p>&#160;</p>
<p>去年我作了一个Lua脚本的C++包装，有许多朋友感兴趣，并尝试使用，我感到受宠若惊。事实上，我作的包装，学习的目的比较强，它还是有许多缺陷的。为了让朋友们少走弯路，我推荐使用LuaPlus作为C++的包装。</p>
<p>LuaPlus是Lua的C++增强，也就是说，LuaPlus本身就是在Lua的源码上进行增强得来的。用它与C++进行合作，是比较好的一个选择。<br>LuaPlus目前版本为：LuaPlus for Lua 5.01 Distribution Build 1080 (February 28, 2004)。大家可以到<a href="http://luaplus.org/" target=_blank><font color=#444444>http://luaplus.org/</font></a> 站点下载：<br>源码&nbsp;&nbsp; (<a href="http://wwhiz.com/LuaPlus/LuaPlus50_Build1081.zip" target=_blank><font color=#444444>http://wwhiz.com/LuaPlus/LuaPlus50_Build1081.zip</font></a>)<br>目标码 (<a href="http://wwhiz.com/LuaPlus/LuaPlus50_Build1081_Win32Binaries.zip" target=_blank><font color=#444444>http://wwhiz.com/LuaPlus/LuaPlus50_Build1081_Win32Binaries.zip</font></a>)</p>
<p>我将在下面说明，如何使用LuaPlus，以及如何更方便的让LuaPlus与C++的类合作无间。</p>
<p>1. 调用Lua脚本</p>
<p>&nbsp;&nbsp;&nbsp; // 创建Lua解释器：<br>&nbsp;&nbsp;&nbsp; LuaStateOwner state; <br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; // 执行Lua脚本：<br>&nbsp;&nbsp;&nbsp; state-&gt;DoString("print('Hello World\n')");<br>&nbsp;&nbsp;&nbsp; // 载入Lua脚本文件并执行：<br>&nbsp;&nbsp;&nbsp; state-&gt;DoFile("C:\\test.lua");<br>&nbsp;&nbsp;&nbsp; // 载入编译后的Lua脚本文件并执行：<br>&nbsp;&nbsp;&nbsp; state-&gt;DoFile("C:\\test.luac");</p>
<p>2. 与Lua脚本互相调用</p>
<p>&nbsp;&nbsp;&nbsp; // 为Lua脚本设置变量<br>&nbsp;&nbsp;&nbsp; state-&gt;GetGlobals().SetNumber("myvalue", 123456);<br>&nbsp;&nbsp;&nbsp; // 获得Lua变量的值<br>&nbsp;&nbsp;&nbsp; int myvalue = state-&gt;GetGlobal("myvalue").GetInteger();<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; // 调用Lua函数<br>&nbsp;&nbsp;&nbsp; LuaFunction&lt;int&gt; luaPrint = state-&gt;GetGlobal("print");<br>&nbsp;&nbsp;&nbsp; luaPrint("Hello World\n");<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; // 让Lua调用C语言函数<br>&nbsp;&nbsp;&nbsp; int add(int a, int b){ return a+b;}<br>&nbsp;&nbsp;&nbsp; state-&gt;GetGlobals().RegisterDirect("add", add);<br>&nbsp;&nbsp;&nbsp; state-&gt;DoString("print(add(3,4))");<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; // 让Lua调用C++类成员函数<br>&nbsp;&nbsp;&nbsp; class Test{public: int add(int a, int b){return a+b;}};<br>&nbsp;&nbsp;&nbsp; Test test;<br>&nbsp;&nbsp;&nbsp; state-&gt;GetGlobals().RegisterDirect("add", test, add);<br>&nbsp;&nbsp;&nbsp; state-&gt;DoString("print(add(3,4))");<br>&nbsp;&nbsp;&nbsp; <br>3. 在Lua脚本中使用C++类<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 这个稍微有点小麻烦。不过，我包装了一个LuaPlusHelper.h的文件，它可以很轻松的完成这个工作。它的实现也很简单，大家可以从源码上来获得如何用纯LuaPlus实现同样的功能。<br>&nbsp;&nbsp;&nbsp; 不过，这里仍然有一个限制没有解决：不能使用虚成员函数。不过考虑到我们仅是在Lua调用一下C++函数，并不是要将C++完美的导入到Lua，这个限制完全可以接受。<br>&nbsp;&nbsp;&nbsp; 另外，类成员变量不能直接在Lua中访问，可以通过类成员函数来访问（比如SetValue/GetValue之类)。</p>
<p>&nbsp;// 下面是一个简单的C++类:&nbsp;&nbsp;&nbsp; <br>&nbsp;class Logger<br>&nbsp;{<br>&nbsp;public:<br>&nbsp;&nbsp;void LOGMEMBER(const char* message)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;printf("In member function: %s\n", message);<br>&nbsp;&nbsp;}<br>&nbsp;<br>&nbsp;&nbsp;Logger()<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;printf("Constructing(%p)...\n", this);<br>&nbsp;&nbsp;&nbsp;v = 10;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;virtual ~Logger()<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;printf("Destructing(%p)...\n", this);<br>&nbsp;&nbsp;}<br>&nbsp;<br>&nbsp;&nbsp;Logger(int n)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;printf(" -- Constructing[%d](%p)...\n", n, this);<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;Logger(Logger* logger)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;printf(" -- Constructing[%p](%p)...\n", logger, this);<br>&nbsp;&nbsp;&nbsp;logger-&gt;LOGMEMBER(" Call From Constructor\n");<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;int SetValue(int val)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;v = val;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;int GetValue()<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;return v;<br>&nbsp;&nbsp;}<br>&nbsp;public:<br>&nbsp;&nbsp;int v;<br>&nbsp;};</p>
<p>&nbsp;&nbsp;&nbsp; // 导入到Lua脚本：<br>&nbsp;&nbsp;&nbsp; LuaClass&lt;Logger&gt;(state)<br>&nbsp;.create("Logger")&nbsp;// 定义构造函数 Logger::Logger()<br>&nbsp;.create&lt;int&gt;("Logger2")&nbsp;&nbsp;// 定义构造函数 Logger::Logger(int)<br>&nbsp;.create&lt;Logger*&gt;("Logger3")&nbsp;// 定义构造函数 Logger::Logger(Logger*)<br>&nbsp;.destroy("Free")&nbsp;&nbsp;// 定义析构函数 Logger::~Logger()<br>&nbsp;.destroy("__gc")&nbsp;&nbsp;// 定义析构函数 Logger::~Logger()<br>&nbsp;.def("lm", &amp;Logger::LOGMEMBER)&nbsp; // 定义成员函数 Logger::LOGMEMBER(const char*)<br>&nbsp;.def("SetValue", &amp;Logger::SetValue)<br>&nbsp;.def("GetValue", &amp;Logger::GetValue);<br>&nbsp;<br>&nbsp;&nbsp;&nbsp; // 在Lua中使用Logger类(1)：<br>&nbsp;&nbsp;&nbsp; state-&gt;DoString(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "l = Logger();"&nbsp;&nbsp;// 调用构造函数 Logger::Logger()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "l.lm('Hello World 1');"&nbsp; // 调用成员函数 Logger::LOGMEMBER(const char*)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "l.Free();"&nbsp;&nbsp;// 调用析构函数 Logger::~Logger()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );</p>
<p>&nbsp;&nbsp;&nbsp; // 在Lua中使用Logger类(2)：<br>&nbsp;&nbsp;&nbsp; state-&gt;DoString(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "m = Logger(10);"&nbsp;// 调用构造函数 Logger::Logger(int)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "m.lm('Hello World 2');"&nbsp; // 调用成员函数 Logger::LOGMEMBER(const char*)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "n = Logger(m);"&nbsp;// 调用构造函数 Logger::Logger(Logger*)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "n.lm('Hello World 3');"&nbsp; // 调用成员函数 Logger::LOGMEMBER(const char*)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "m.SetValue(11);"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "print(m.GetValue());"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "m,n = nil, nil;"&nbsp;// m,n 将由Lua的垃极回收来调用析构函数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );</p>
<p>4. 将一组C函数归类到Lua模块</p>
<p>&nbsp;&nbsp;&nbsp; //同上面一样，我采用LuaPlusHelper.h来简化：<br>&nbsp;&nbsp;&nbsp; LuaModule(state, "mymodule")<br>&nbsp;.def("add", add)<br>&nbsp;.def("add2", test, add);<br>&nbsp;<br>&nbsp;&nbsp;&nbsp; state-&gt;DoString(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "print(mymodule.add(3,4));"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "print(mymodule.add2(3,4));"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );</p>
<p>5. 使用Lua的Table数据类型<br>&nbsp;&nbsp;&nbsp; // 在Lua中创建Table<br>&nbsp;&nbsp;&nbsp; LuaObject table = state-&gt;GetGlobals().CreateTable("mytable");<br>&nbsp;&nbsp;&nbsp; table.SetInteger("m", 10);<br>&nbsp;&nbsp;&nbsp; table.SetNumber("f", 1.99);<br>&nbsp;&nbsp;&nbsp; table.SetString("s", "Hello World");<br>&nbsp;&nbsp;&nbsp; table.SetWString("ch", L"你好");<br>&nbsp;&nbsp;&nbsp; table.SetString(1, "What");<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; // 相当于Lua中的：<br>&nbsp;&nbsp;&nbsp; // mytable = {m=10, f=1.99, s="Hello World", ch=L"你好", "What"}<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; // 也可以使用table作为key和value:<br>&nbsp;&nbsp;&nbsp; state-&gt;GetGlobals().CreateTable("nexttable")<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .SetString(table, "Hello")<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .SetObject("obj", table);<br>&nbsp;&nbsp;&nbsp; // 相当于Lua中的：<br>&nbsp;&nbsp;&nbsp; // nexttable = {mytable="Hello", obj=mytable}<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; //获得Table的内容：<br>&nbsp;&nbsp;&nbsp; LuaObject t2 = state-&gt;GetGlobals("mytable");<br>&nbsp;&nbsp;&nbsp; int m = t2.GetByName("m").GetInteger();<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; LuaObject t3 = state-&gt;GetGlobals("nexttable");<br>&nbsp;&nbsp;&nbsp; std::string str = t3.GetByObject(t2).GetString();<br>&nbsp;&nbsp;&nbsp; <br>6&nbsp; 遍历Table</p>
<p>&nbsp;LuaStateOwner state;<br>&nbsp;state.DoString( "MyTable = { Hi = 5, Hello = 10, Yo = 6 }" );<br>&nbsp;<br>&nbsp;LuaObject obj = state.GetGlobals()[ "MyTable" ];<br>&nbsp;for ( LuaTableIterator it( obj ); it; it.Next() )<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp; const char* key = it.GetKey().GetString();<br>&nbsp;&nbsp;&nbsp;&nbsp; int num = it.GetValue().GetInteger();<br>&nbsp;}</p>
<p>篇尾</p>
<p>上面我只是简单的举一些例子来说明LuaPlus以及LuaPlusHelper的使用方法，具体文档请参见LuaPlus。</p>
<p>需要下载LuaPlusHelper，请点这里：<br><a href="http://www.d2-life.com/LBS/attachments/month_200509/06_zwo3LuaPlusHelper.zip" target=_blank><font color=#444444>http://www.d2-life.com/LBS/attachments/month_200509/06_zwo3LuaPlusHelper.zip</font></a></p>
<p>&#160;</p>
</div>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113183.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 22:42 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113183.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转贴】Lua 程序设计初步 </title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113182.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 14:41:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113182.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113182.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113182.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113182.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113182.html</trackback:ping><description><![CDATA[<div class=postText>作者： 沐枫 （第二人生成员）<br>版权所有转载请注明原出处<br>主页：第二人生 <a href="http://www.d2-life.com/" target=_blank><font color=#002c99>http://www.d2-life.com</font></a><br>　　　<a href="http://www.d2-life.com/LBS/blogview.asp?logID=39" target=_blank><font color=#002c99>http://www.d2-life.com/LBS/blogview.asp?logID=39</font></a><br><br>　　在这篇文章中，我想向大家介绍如何进行Lua程序设计。我假设大家都学过至少一门编程语言，比如Basic或C，特别是C。因为Lua的最大用途是在宿主程序中作为脚本使用的。<br>　　Lua 的语法比较简单，学习起来也比较省力，但功能却并不弱。<br>　　在Lua中，一切都是变量，除了关键字。请记住这句话。<br><br>I.&nbsp;&nbsp;首先是注释<br>　　写一个程序，总是少不了注释的。<br>　　在Lua中，你可以使用单行注释和多行注释。<br>　　单行注释中，连续两个减号"--"表示注释的开始，一直延续到行末为止。相当于C++语言中的"//"。<br>　　多行注释中，由"--[["表示注释开始，并且一直延续到"]]"为止。这种注释相当于C语言中的"/*&#8230;*/"。在注释当中，"[["和"]]"是可以嵌套的。<br>II.&nbsp;&nbsp;Lua编程<br>　　经典的"Hello world"的程序总是被用来开始介绍一种语言。在Lua中，写一个这样的程序很简单：<br>　　print("Hello world")<br>　　在Lua中，语句之间可以用分号"；"隔开，也可以用空白隔开。一般来说，如果多个语句写在同一行的话，建议总是用分号隔开。<br>　　Lua 有好几种程序控制语句，如：<br><br>　　条件控制：if 条件 then &#8230; elseif 条件 then &#8230; else &#8230; end<br>　　While循环：while 条件 do &#8230; end<br>　　Repeat循环：repeat &#8230; until 条件<br>　　For循环：for 变量 = 初值，终点值，步进 do &#8230; end<br>　　For循环：for 变量1，变量2，&#8230; ，变量N in表或枚举函数 do &#8230; end<br><br>　　注意一下，for的循环变量总是只作用于for的局部变量，你也可以省略步进值，这时候，for循环会使用1作为步进值。<br>　　你可以用break来中止一个循环。<br>　　如果你有程序设计的基础，比如你学过Basic，C之类的，你会觉得Lua也不难。但Lua有几个地方是明显不同于这些程序设计语言的，所以请特别注意。<br><br>　　．语句块<br>　　　　语句块在C++中是用"{"和"}"括起来的，在Lua中，它是用do 和 end 括起来的。比如： <br>　　　　do print("Hello") end<br>　　　　你可以在 函数 中和 语句块 中定局部变量。<br><br>　　．赋值语句<br>　　　　赋值语句在Lua被强化了。它可以同时给多个变量赋值。<br>　　　　例如：<br>　　　　a,b,c,d=1,2,3,4<br>　　　　甚至是：<br>　　　　a,b=b,a&nbsp;&nbsp;-- 多么方便的交换变量功能啊。<br>　　　　在默认情况下，变量总是认为是全局的。假如你要定义局部变量，则在第一次赋值的时候，需要用local说明。比如：<br>　　　　local a,b,c = 1,2,3&nbsp;&nbsp;-- a,b,c都是局部变量<br><br>　　．数值运算<br>　　　　和C语言一样，支持 +, -, *, /。但Lua还多了一个"^"。这表示指数乘方运算。比如2^3 结果为8, 2^4结果为16。<br>　　　　连接两个字符串，可以用".."运处符。如：<br>　　　　"This a " .. "string." -- 等于 "this a string"<br><br>　　．比较运算<br>　　　　&lt; &gt; &lt;= &gt;= == ~=<br>　　　　分别表示 小于，大于，不大于，不小于，相等，不相等<br>　　　　所有这些操作符总是返回true或false。<br>　　　　对于Table，Function和Userdata类型的数据，只有 == 和 ~=可以用。相等表示两个变量引用的是同一个数据。比如：<br>　　　　a={1,2}<br>　　　　b=a<br>　　　　print(a==b, a~=b)&nbsp;&nbsp;-- true, false<br>　　　　a={1,2}<br>　　　　b={1,2}<br>　　　　print(a==b, a~=b)&nbsp;&nbsp;-- false, true<br><br>　　．逻辑运算<br>　　　　and, or, not<br>　　　　其中，and 和 or 与C语言区别特别大。<br>　　　　在这里，请先记住，在Lua中，只有false和nil才计算为false，其它任何数据都计算为true，0也是true！<br>　　　　and 和 or的运算结果不是true和false，而是和它的两个操作数相关。<br>　　　　a and b：如果a为false，则返回a；否则返回b<br>　　　　a or b：如果 a 为true，则返回a；否则返回b<br><br>　　　　举几个例子：<br>　　　　 print(4 and 5) --&gt; 5<br>　　　　 print(nil and 13) --&gt; nil<br>　　　　 print(false and 13) --&gt; false<br>　　　　 print(4 or 5) --&gt; 4<br>　　　　 print(false or 5) --&gt; 5<br><br>　　　　在Lua中这是很有用的特性，也是比较令人混洧的特性。<br>　　　　我们可以模拟C语言中的语句：x = a? b : c，在Lua中，可以写成：x = a and b or c。<br>　　　　最有用的语句是： x = x or v，它相当于：if not x then x = v end 。<br><br>　　．运算符优先级，从高到低顺序如下：<br>　　　　^<br>　　　　not - （一元运算）<br>　　　　 * /<br>　　　　 + -<br>　　　　 ..（字符串连接）<br>　　　　 &lt; &gt; &lt;= &gt;= ~= ==<br>　　　　 and<br>　　　　 or<br><br>III.&nbsp;&nbsp;关键字<br>　　关键字是不能做为变量的。Lua的关键字不多，就以下几个：<br>　　and break do else elseif<br>　　end false for function if<br>　　in local nil not or<br>　　repeat return then true until　while<br><br>IV.&nbsp;&nbsp;变量类型<br>　　怎么确定一个变量是什么类型的呢？大家可以用type()函数来检查。Lua支持的类型有以下几种：<br><br>　　Nil&nbsp;&nbsp;空值，所有没有使用过的变量，都是nil。nil既是值，又是类型。<br>　　Boolean&nbsp;&nbsp;布尔值<br>　　Number&nbsp;&nbsp;数值，在Lua里，数值相当于C语言的double<br>　　String&nbsp;&nbsp;字符串，如果你愿意的话，字符串是可以包含'\0'字符的<br>　　Table&nbsp;&nbsp;关系表类型，这个类型功能比较强大，我们在后面慢慢说。<br>　　Function&nbsp;&nbsp;函数类型，不要怀疑，函数也是一种类型，也就是说，所有的函数，它本身就是一个变量。<br>　　Userdata&nbsp;&nbsp;嗯，这个类型专门用来和Lua的宿主打交道的。宿主通常是用C和C++来编写的，在这种情况下，Userdata可以是宿主的任意数据类型，常用的有Struct和指针。<br>　　Thread　　&nbsp;&nbsp;线程类型，在Lua中没有真正的线程。Lua中可以将一个函数分成几部份运行。如果感兴趣的话，可以去看看Lua的文档。<br><br>V.&nbsp;&nbsp;变量的定义<br>　　所有的语言，都要用到变量。在Lua中，不管你在什么地方使用变量，都不需要声明，并且所有的这些变量总是全局变量，除非，你在前面加上"local"。<br>　　这一点要特别注意，因为你可能想在函数里使用局部变量，却忘了用local来说明。<br>　　至于变量名字，它是大小写相关的。也就是说，A和a是两个不同的变量。<br>　　定义一个变量的方法就是赋值。"＝"操作就是用来赋值的<br>　　我们一起来定义几种常用类型的变量吧。<br>　　A.&nbsp;&nbsp;Nil<br>　　　　正如前面所说的，没有使用过的变量的值，都是Nil。有时候我们也需要将一个变量清除，这时候，我们可以直接给变量赋以nil值。如：<br>　　　　var1=nil&nbsp;&nbsp;-- 请注意 nil 一定要小写<br><br>　　B.&nbsp;&nbsp;Boolean<br>　　　　布尔值通常是用在进行条件判断的时候。布尔值有两种：true 和 false。在Lua中，只有false和nil才被计算为false，而所有任何其它类型的值，都是true。比如0，空串等等，都是true。不要被C语言的习惯所误导，0在Lua中的的确确是true。你也可以直接给一个变量赋以Boolean类型的值，如：<br>　　　　varboolean = true<br><br>　　C.&nbsp;&nbsp;Number<br>　　　　在Lua中，是没有整数类型的，也不需要。一般情况下，只要数值不是很大（比如不超过100,000,000,000,000），是不会产生舍入误差的。在很多CPU上，实数的运算并不比整数慢。<br>　　　　实数的表示方法，同C语言类似，如：<br>　　　　4 0.4 4.57e-3 0.3e12 5e+20<br><br>　　D.&nbsp;&nbsp;String<br>　　　　字符串，总是一种非常常用的高级类型。在Lua中，你可以非常方便的定义很长很长的字符串。<br>　　　　字符串在Lua中有几种方法来表示，最通用的方法，是用双引号或单引号来括起一个字符串的，如：<br>　　　　"This is a string."<br>　　　　和C语言相同的，它支持一些转义字符，列表如下：<br>　　　　\a&nbsp;&nbsp;bell<br>　　　　\b&nbsp;&nbsp;back space<br>　　　　\f&nbsp;&nbsp;form feed<br>　　　　\n&nbsp;&nbsp;newline<br>　　　　\r&nbsp;&nbsp;carriage return<br>　　　　\t&nbsp;&nbsp;horizontal tab<br>　　　　\v&nbsp;&nbsp;vertical tab<br>　　　　\\&nbsp;&nbsp;backslash<br>　　　　\"&nbsp;&nbsp;double quote<br>　　　　\'&nbsp;&nbsp;single quote<br>　　　　\[&nbsp;&nbsp;left square bracket<br>　　　　\]&nbsp;&nbsp;right square bracket<br><br>　　　　由于这种字符串只能写在一行中，因此，不可避免的要用到转义字符。加入了转义字符的串，看起来实在是不敢恭维，比如：<br>　　　　"one line\nnext line\n\"in quotes\", 'in quotes'"<br>　　　　一大堆的"\"符号让人看起来很倒胃口。如果你与我有同感，那么，我们在Lua中，可以用另一种表示方法：用"[["和"]]"将多行的字符串括起来，如：<br>　　　　page = [[<br>　　　　&lt;HTML&gt;<br>　　　　　　&lt;HEAD&gt;<br>　　　　　　　　&lt;TITLE&gt;An HTML Page&lt;/TITLE&gt;<br>　　　　　　&lt;/HEAD&gt;<br>　　　　　　&lt;BODY&gt;<br>　　　　　　　　&lt;A HREF="<a href=""><font color=#444444>lua</font></a>' target=_blank&gt;<font color=#002c99>http://www.lua.org"&gt;Lua&lt;/A&gt;</font><br>　　　　　　　　[[a text between double brackets]]<br>　　　　　　&lt;/BODY&gt;<br>　　　　&lt;/HTML&gt;<br>　　　　]]<br><br>　　　　值得注意的是，在这种字符串中，如果含有单独使用的"[["或"]]"就仍然得用"\["或"\]"来避免歧义。当然，这种情况是极少会发生的。<br><br>　　E.&nbsp;&nbsp;Table<br>　　　　关系表类型，这是一个很强大的类型。我们可以把这个类型看作是一个数组。只是C语言的数组，只能用正整数来作索引；在Lua中，你可以用任意类型来作数组的索引，除了nil。同样，在C语言中，数组的内容只允许一种类型；在Lua中，你也可以用任意类型的值来作数组的内容，除了nil。<br>　　　　Table的定义很简单，它的主要特征是用"{"和"}"来括起一系列数据元素的。比如：<br><br>　　　　T1 = {}&nbsp;&nbsp;-- 定义一个空表<br>　　　　T1[1]=10&nbsp;&nbsp;-- 然后我们就可以象C语言一样来使用它了。<br>　　　　T1["John"]={Age=27, Gender="Male"}<br>　　　　这一句相当于：<br>　　　　T1["John"]={}&nbsp;&nbsp;-- 必须先定义成一个表，还记得未定义的变量是nil类型吗<br>　　　　T1["John"]["Age"]=27<br>　　　　T1["John"]["Gender"]="Male"<br>　　　　当表的索引是字符串的时候，我们可以简写成：<br>　　　　T1.John={}<br>　　　　T1.John.Age=27<br>　　　　T1.John.Gender="Male"<br>　　　　或<br>　　　　T1.John{Age=27, Gender="Male"}<br>　　　　这是一个很强的特性。<br><br>　　　　在定义表的时候，我们可以把所有的数据内容一起写在"{"和"}"之间，这样子是非常方便，而且很好看。比如，前面的T1的定义，我们可以这么写：<br><br>　　　　T1=<br>　　　　{<br>　　　　　　10,&nbsp;&nbsp;-- 相当于 [1] = 10<br>　　　　　　[100] = 40,<br>　　　　　　John=&nbsp;&nbsp;-- 如果你原意，你还可以写成：["John"] =<br>　　　　　　{<br>　　　　　　　　Age=27,&nbsp;&nbsp; -- 如果你原意，你还可以写成：["Age"] =27<br>　　　　　　　　Gender=Male&nbsp;&nbsp; -- 如果你原意，你还可以写成：["Gender"] =Male<br>　　　　　　},<br>　　　　　　20&nbsp;&nbsp;-- 相当于 [2] = 20<br>　　　　}<br><br>　　　　看起来很漂亮，不是吗？我们在写的时候，需要注意三点：<br>　　　　第一，所有元素之间，总是用逗号"，"隔开；<br>　　　　第二，所有索引值都需要用"["和"]"括起来；如果是字符串，还可以去掉引号和中括号；<br>　　　　第三，如果不写索引，则索引就会被认为是数字，并按顺序自动从1往后编；<br><br>　　　　表类型的构造是如此的方便，以致于常常被人用来代替配置文件。是的，不用怀疑，它比ini文件要漂亮，并且强大的多。<br><br>　　F.&nbsp;&nbsp;Function<br>　　　　函数，在Lua中，函数的定义也很简单。典型的定义如下：<br>　　　　function add(a,b)&nbsp;&nbsp;-- add 是函数名字，a和b是参数名字<br>　　　　 return a+b&nbsp;&nbsp;-- return 用来返回函数的运行结果<br>　　　　end<br><br>　　　　请注意，return语言一定要写在end之前。假如你非要在中间放上一句return，那么请写成：do return end。<br>　　　　还记得前面说过，函数也是变量类型吗？上面的函数定义，其实相当于：<br>　　　　add = function (a,b) return a+b end<br>　　　　当你重新给add赋值时，它就不再表示这个函数了。你甚至可以赋给add任意数据，包括nil （这样，你就清除了add变量）。Function是不是很象C语言的函数指针呢？<br><br>　　　　和C语言一样，Lua的函数可以接受可变参数个数，它同样是用"&#8230;"来定义的，比如：<br>　　　　function sum (a,b,&#8230;)<br>　　　　如果想取得&#8230;所代表的参数，可以在函数中访问arg局部变量（表类型）得到。<br>　　　　如 sum(1,2,3,4)<br>　　　　则，在函数中，a = 1, b = 2, arg = {3, 4}<br>　　　　更可贵的是，它可以同时返回多个结果，比如：<br>　　　　function s()<br>　　　　　　return 1,2,3,4<br>　　　　end<br>　　　　a,b,c,d = s()&nbsp;&nbsp;-- 此时，a = 1, b = 2, c = 3, d = 4<br><br>　　　　前面说过，表类型可以拥有任意类型的值，包括函数！因此，有一个很强大的特性是，拥有函数的表，哦，我想更恰当的应该说是对象吧。Lua可以使用面向对象编程了。不信？那我举例如下：<br><br>　　　　t =<br>　　　　{<br>　　　　 Age = 27<br>　　　　 add = function(self, n) self.Age = self.Age+n end<br>　　　　}<br>　　　　print(t.Age)&nbsp;&nbsp;-- 27<br>　　　　t.add(t, 10)<br>　　　　print(t.Age)&nbsp;&nbsp;-- 37<br><br>　　　　不过，t.add(t,10) 这一句实在是有点土对吧？没关系，在Lua中，你可以简写成：<br>　　　　t:add(10)&nbsp;&nbsp;&nbsp;&nbsp;-- 相当于 t.add(t,10)<br><br>　　G.&nbsp;&nbsp;Userdata 和 Thread<br>　　　　这两个类型的话题，超出了本文的内容，就不打算细说了。<br><br>VI.&nbsp;&nbsp;结束语<br>　　就这么结束了吗？当然不是，接下来，需要用Lua解释器，来帮助你理解和实践了。这篇小文只是帮助你大体了解Lua的语法。如果你有编程基础，相信会很快对Lua上手了。<br>　　就象C语言一样，Lua提供了相当多的标准函数来增强语言的功能。使用这些标准函数，你可以很方便的操作各种数据类型，并处理输入输出。有关这方面的信息，你可以参考《Programming in Lua 》一书，你可以在网络上直接观看电子版，网址为：<a href="http://www.lua.org/pil/index.html" target=_blank><font color=#002c99>http://www.lua.org/pil/index.html</font></a><br>　　当然，Lua的最强大的功能是能与宿主程序亲蜜无间的合作，因此，下一篇文章，我会告诉大家，如何在你的程序中使用Lua语言作为脚本，使你的程序和Lua脚本进行交互。<br></div>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113182.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 22:41 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113182.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转贴】如何在C++中集成LUA脚本(LuaWrapper For C++篇) </title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113181.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 14:39:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113181.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113181.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113181.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113181.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113181.html</trackback:ping><description><![CDATA[作者： 沐枫 （第二人生成员）<br>版权所有转载请注明原出处<br>主页：第二人生 <a href="http://www.d2-life.com/" target=_blank><font color=#444444>http://www.d2-life.com</font></a><br>　　　<a href="http://www.d2-life.com/LBS/blogview.asp?logID=41" target=_blank><font color=#444444>http://www.d2-life.com/LBS/blogview.asp?logID=41</font></a><br><br>为什么要用Lua作脚本？<br>　　使用Lua作脚本，主要是因为它小巧玲珑（体积小，运行快），而且它的语法又比较简单明了。不过，使用LuaAPI将Lua引擎集成到程序中，确实有一些不方便——用落木随风网友的话来说，就是"就象用汇编"。当然，现在你不用再这么辛苦了，因为你可以使用LuaWrapper For C++。使用这个工具，在C++中集成Lua脚本就是轻而易举的事。你原有的C++函数和类，几乎不需要任何改变，就可以与Lua脚本共享。<br>　　我们接下来，用实例来说明，如何用LuaWrapper来集成Lua脚本到你的程序中去。<br><br>1.&nbsp;&nbsp;创建Lua引擎<br>　　LuaWrap lua; 或者 LuaWrap* lua = new LuaWrap;<br>　　创建一个LuaWrap对象，就是创建一个Lua脚本引擎。并且根据Lua的特性，你可以创建任意多个Lua引擎，甚至可以分布在不同的线程当中。<br><br>2.&nbsp;&nbsp;装载并执行脚本程序<br>　　你可以从缓冲区中装载Lua脚本：<br>　　lua.LoadString(<br>　　　　"print('Hello World')"<br>　　);<br>　　当然，你也可以从文件中装入，并执行Lua脚本：<br>　　Lua.LoadFile("./test.lua");<br>　　Lua的脚本，可以是源代码，也可以经过编译后的中间代码。也许你对编译后的中间代码更感兴趣——如果你不希望让源代码赤裸裸的袒露在大家的眼前。<br><br>3.&nbsp;&nbsp;获取和设置Lua变量<br>　　能够获取和设置脚本变量的内容，是一个最基本的功能。你可以使用GetGlobal和SetGlobal函数来做到这一点：<br>　　(1)&nbsp;&nbsp;获取变量：<br>　　　　int a = lua.GetGlobal&lt;int&gt;("a");<br>　　　　LuaTable table = lua.GetGlobal&lt;LuaTable&gt;("t");<br>　　　　这里，&lt;&gt; 里头的类型，就是想要的变量的类型。<br>　　(2)&nbsp;&nbsp;设置变量：<br>　　　　lua.SetGlobal("a", a); <br>　　　　lua.SetGlobal("t", table);<br><br>4.&nbsp;&nbsp;调用Lua函数<br>　　使用Call函数，就可以很简单的从你的程序中调用Lua函数：<br>　　lua.Call&lt;void&gt;("print", "Hello World");<br>　　int sum = lua.Call&lt;int&gt;("add", 2, 3);<br>　　这里，&lt;&gt; 里头的类型是返回值的类型。<br><br>5.&nbsp;&nbsp;如何让Lua也能调用C++的函数<br>　　精采的地方来了。假如有下面这样的一个函数：<br>　　int add(int a, int b)<br>　　{<br>　　　　return a + b;<br>　　}<br>　　如果想让它能够让Lua使用，只需将它注册到Lua引擎当中就可以了：<br>　　lua.RegisterFunc("add", int(int,int), add);<br>　　这样，Lua中就可以用直接使用了：<br>　　（Lua脚本）sum = add(1, 3) <br><br>　　(*) RegisterFunc的功能，就是让你把C++的函数注册到Lua中，供Lua脚本使用。<br>　　　　第一个参数，是想要在Lua中用的函数名。<br>　　　　第二个参数，是C++中函数的原型； C++允许函数重载的，你可以使用函数原型，来选择需要注册到Lua引擎中的那个函数。<br>　　　　第三个参数，就是C++中函数的指针了。<br><br>6.&nbsp;&nbsp;如何能让C++的类在Lua中使用<br>　　我们先看看下面这个C++类：<br>class MyArray<br>{<br>&nbsp;&nbsp;std::vector&lt;double&gt; array;<br>public:<br>&nbsp;&nbsp;void setvalue(int index, double value);<br>&nbsp;&nbsp;double getvalue(int index);<br>&nbsp;&nbsp;int size();<br>&nbsp;&nbsp;const char* ToString();<br>};<br><br>　　你准备要让Lua能够自由访问并操作这个类。很简单，你只需增加几个宏定义就可以了：<br><br>class MyArray<br>{<br>&nbsp;&nbsp;std::vector&lt;double&gt; array;<br>public:<br>&nbsp;&nbsp;void setvalue(int index, double value);<br>&nbsp;&nbsp;double getvalue(int index);<br>&nbsp;&nbsp;int size();<br>&nbsp;&nbsp;const char* ToString();<br>&nbsp;&nbsp;// 将一个 class 作为一个 Lua 对象是很容易的，只需要增加以下宏定义。<br>&nbsp;&nbsp;DEFINE_TYPENAME("My.array");<br>&nbsp;&nbsp;BEGIN_REGLUALIB("array")<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LUALIB_ITEM_create("new", MyArray )&nbsp;&nbsp;// 创建MyArray (注：由于发表的原因，create应为全部大写)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LUALIB_ITEM_DESTROY("del", MyArray )&nbsp;&nbsp;// 消除MyArray。<br>&nbsp;&nbsp;END_REGLUALIB()<br>&nbsp;&nbsp;BEGIN_REGLUALIB_MEMBER()<br>&nbsp;&nbsp;&nbsp;&nbsp;LUALIB_ITEM_FUNC("size", int (MyArray*), &amp;MyArray::size)<br>&nbsp;&nbsp;&nbsp;&nbsp;LUALIB_ITEM_FUNC("__getindex", double(MyArray*, int), &amp;MyArray::getvalue)&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;LUALIB_ITEM_FUNC("__newindex", void (MyArray*, int, double), &amp;MyArray::setvalue)<br>&nbsp;&nbsp;&nbsp;&nbsp;LUALIB_ITEM_FUNC("__tostring", const char* (MyArray*), &amp;MyArray::ToString)<br>&nbsp;&nbsp;&nbsp;&nbsp;LUALIB_ITEM_DESTROY("__gc", MyArray ) &nbsp;&nbsp;// 垃圾收集时消除对象用。<br>&nbsp;&nbsp;END_REGLUALIB_MEMBER()<br>};<br><br>　　只要有了这些宏定义，这个类就是可以在Lua中使用的类了，我们就可以在Lua中注册这个类了：<br>　　lua.Register&lt;MyArray&gt;()<br><br>　　这样注册以后，我们在Lua中就可以使用这个类了：<br>　　a = array.new()&nbsp;&nbsp;-- 创建对象，相当于 a = new Myarray<br>　　a[1] = 10&nbsp;&nbsp;-- 调用__newindex，也就是C++中的 a-&gt;setvalue(1, 10)<br>　　a[2] = 20&nbsp;&nbsp;-- 调用__newindex，也就是C++中的 a-&gt;setvalue(2, 20)<br>　　print(<br>　　　　a,&nbsp;&nbsp;-- 调用 __tostring，也就是C++中的 a-&gt;ToString()<br>　　　　a:size(), -- 相当于C++中的 a-&gt;size()<br>　　　　a[1], -- 调用__getindex，也就是C++中的a-&gt;getvalue(1)<br>　　　　a[2]) --调用__getindex，也就是C++中的a-&gt;getvalue(2)<br>　　array.del(a)&nbsp;&nbsp;-- 清除对象，相当于 delete a<br>　　a = nil&nbsp;&nbsp;-- 清空 a，很象C++中的 a = NULL<br><br>　　当然，你也可以不用del这个对象，而是等待Lua帮你自动进行垃圾回收。在Lua进行垃圾回收时，它会自动调用这个对象的 __gc ，相当于 delete。<br><br>　　那么，在C++中要创建MyArray对象，并且传递给Lua全局变量怎么办？就象前面讲过的一样，使用SetGlobal：<br>　　MyArray* a = new MyArray; <br>　　lua.SetGlobal("a", a);<br>　　要获取该对象，同样的，应该使用GetGlobal：<br>　　MyArray* a = lua.GetGlobal&lt;MyArray&gt;("a");<br>　　<br>　　对于传递给Lua的对象，就让Lua来管理该对象的生存周期好了。如果你非要删除它的话，你可以使用DelGlobalObject：<br>　　lua.DelGlobalObject&lt;MyArray&gt;("a");<br>　　不过这么做的话，你应当明白你在做什么，因为在Lua的脚本中，可能已经在多处引用了这个对象了。删除了其中一个，将导致其它引用对象失效，从而可能引致系统崩溃。<br><br>　　(1)&nbsp;&nbsp;DEFINE_TYPENAME("My.array");<br>　　　　定义类型的名称。在Lua中，这个类型名称是唯一用来识别C++类型的，你必须为不同的对象给予不同的名称。<br><br>　　(2)&nbsp;&nbsp;BEGIN_REGLUALIB("array") &#8230; END_REGLUALIB()<br>　　　　你可以为一个对象定义一个程序库，"array"就是程序库的名字。在程序库中定义的函数是全局函数，在Lua中，使用该函数，需要在函数前加上库的名字，如：array.new（）。通常，程序库会包含创建对象的方法。如：<br>　　　　LUALIB_ITEM_create("new", MyArray )&nbsp;&nbsp;// 创建MyArray (注：由于发表的原因，create应为全部大写)<br>　　　　这样子，你才能在Lua中创建MyArray：<br>　　　　a = array.new()<br>　　<br>　　　　你也可以选择增加一个删除对象操作：<br>　　　　LUALIB_ITEM_DESTROY("del", MyArray ) &nbsp;&nbsp;// 删除MyArray<br>　　　　这样，你就可以直接删除一个对象了：<br>　　　　array.del(a)<br><br>　　(3)&nbsp;&nbsp;BEGIN_REGLUALIB_MEMBER() &#8230;END_REGLUALIB_MEMBER()<br>　　　　在此处，你可以定义对象的成员函数，也可以重载对象的操作符——是的，就象C++的operator重载。例如：<br>　　　　LUALIB_ITEM_FUNC("__newindex", void (MyArray*, int, double), &amp;MyArray::setvalue)<br>　　　　就是重载 operator[] 操作符。Lua中可重载的操作符还有许多，如：<br><br>　　　　__getindex：操作符[]，支持读取访问，如 v = a[10]<br>　　　　__newindex：操作符[]，支持赋值访问，如 a[10] = 1.22<br>　　　　__tostring：将变量转换成字串__add：等同于operator +<br>　　　　__add：操作符 ＋<br>　　　　__sub：操作符 &#8211;<br>　　　　__mul：操作符 &#215;<br>　　　　__div：操作符 &#247;<br>　　　　__pow：操作符 ^ (乘方)<br>　　　　__unm：一元操作符 &#8211;<br>　　　　__concat：操作符 .. (字符串连接)<br>　　　　__eq：操作符 == (a ~= b等价于 not a == b)<br>　　　　__lt：操作符 &lt; (a &gt; b 等价于 b &lt; a)<br>　　　　__le：操作符 &lt;= (a &gt;= b 等价于 b &lt;= a，要注意的是，如果没有定义"__le"，则Lua将会尝试将a&lt;=b 转换成 not (b &lt; a) )<br><br>　　　　__gc：在垃圾回收时调用此函数，相当于C++的析构函数。强烈建议定义此操作符，以免造成内存泄漏等情况。比如：<br>　　　　LUALIB_ITEM_DESTROY("__gc", MyArray ) &nbsp;&nbsp;// 垃圾收集时消除对象用。<br><br>　　　　(注) 这里要说明一下，在lua中，访问索引操作符是__index，不是__getindex，在luaWrapper库中，为了方便使用，将其映射为__getindex，同时，对__index的定义将会被忽略。<br><br>　　　　就这么简单。假如你已经有现成的类，而你没有修改该类的权力，如何将其加入到Lua中呢？答案就是，继承它，将把派生类加入到Lua中。<br><br>结束语<br>　　LuaWrapper 需要用到boost库的支持：boost/type_traits.hpp, boost/function.hpp, boost/bind.hpp，它使用了C++的模板部份特化，因此，C++编译器如果不支持此特性，将无法编译。目前支持此特性的编译器已经有很多。在VisualStudo产品系列中，只有VC7.1能支持此特性，因此，您如果正在使用VisualStudio，请确认你用的是VisualStudio2003。<br>　　如果你觉得 LuaWrapper For C++ 能够帮助你，我会感觉很荣幸。我很愿意将这个程序库分享给大家。顺便一提的是，如果你在使用过程中发现BUG，或是有好的建议，希望您能与我联系。你在使用过程中，请不要删除文件中的署名信息；如果你修改了程序库，请您在修改的文件中加入您的修改说明。当然，我会非常欢迎您能将修改后的程序回馈给我。我会继续优化并完善它。<br><br>=============================================================<br><br><a href="http://www.d2-life.com/lbs/attachments/month_200407/22_1xp4LuaWrapper.zip"><img src="http://www.d2-life.com/lbs/images/icon_save.gif" align=absMiddle border=0><font color=#444444><strong>File:</strong> Click Here Download: LuaWrapper For C++</font></a><br><a href="http://www.d2-life.com/lbs/attachments/month_200407/22_85waTestLua.zip"><font color=#444444><img src="http://www.d2-life.com/lbs/images/icon_save.gif" align=absMiddle border=0><strong>File:</strong> Click Here Download: LuaWrapper test program</font></a><br>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113181.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 22:39 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113181.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转贴】通过例子学习Lua </title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113180.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 14:38:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113180.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113180.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113180.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113180.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113180.html</trackback:ping><description><![CDATA[<strong><font size=6>一.Hello World</font> <br><br>1.前言<br></strong>　　<br>　　偶最近在学习Lua, 所以写出心得和大家共享, 争取一天写一篇, 嘿嘿.<br>　　才开始学所以内容很浅, 希望大家包涵.<br>　　Lua是一种完全免费的脚本语言, 可以和C/C++语言紧密结合,<br>　　它的官方网站在http://www.lua.org. 在网站上可以下载到lua的源码, 没有可<br>　　执行版本, 不过不用担心, 因为lua源码可以在任何一种C/C++的编译器上编译.<br>　　<br>　　如果要学习Lua, 官方网站上的Reference是必备的，上面有每个命令的用法，非常详细。<br>　　参考手册 http://www.lua.org/manual/5.0/<br>　　作者写的Programming in Lua http://www.lua.org/pil/<br>　　<br><strong>2.编译</strong><br>　　如果用的VC6, 可以下载所需的project文件,地址在<br>　　http://sourceforge.net/project/showfiles.php?group_id=32250&amp;package_id=115604<br>　　VSNET2003可以下载这个sln文件http://home.comcast.net/~vertigrated/lua/vs7.zip<br>　　偶用的是cygwin和linux, 打入以下命令即可,<br>　　tar -zxvf lua-5.0.2.tar.gz<br>　　cd lua-5.0.2<br>　　sh ./configure<br>　　make<br>　　这样就OK了。<br>　　为了以后使用方便，最好把bin目录加入到path里面。<br>　　<br><strong>3."Hello, world!"</strong><br>　　现在开始偶们的第一个小程序"Hello, world!"<br>　　把以下程序打入文件e01.lua<br>　　<br>　　例1:e01.lua<br>　　-- Hello World in Lua<br>　　print("Hello World.")<br>　　<br>　　Lua有两种执行方式，一种是嵌入到C程序中执行，还有一种是直接从命令行方式下执行。<br>　　这里为了调试方便，采用第二种方式，执行命令 lua e01.lua<br>　　<br>　　输出结果应该是：<br>　　Hello World.<br>　　<br><strong>4.程序说明</strong><br>　　第一行 -- Hello World in Lua<br>　　这句是注释，其中--和C++中的//意思是一样的<br>　　第二行 print("Hello World.")<br>　　调用lua内部命令print，输出"Hello World."字符串到屏幕，Lua中的字符串全部是由"括起来的。<br>　　这个命令是一个函数的调用，print是lua的一个函数，而"Hello World."是print的参数。<br>　　<br><strong>5.试试看</strong><br>　　在Lua中有不少字符串的处理操作，本次的课后试试看的内容就是，找出连接两个字符串的操作，<br>　　并且print出来。 <br><br><font size=6><strong>二.流程控制</strong></font><br><br><strong>1. 函数的使用<br></strong>　　以下程序演示了如何在Lua中使用函数, 及局部变量<br>　　例e02.lua<br>　　-- functions<br>　　function pythagorean(a, b)<br>　　local c2 = a^2 + b^2<br>　　return sqrt(c2)<br>　　end<br>　　print(pythagorean(3,4))<br>　　<br>　　运行结果<br>　　5<br>　　<br>　　程序说明<br>　　在Lua中函数的定义格式为:<br>　　function 函数名(参数)<br>　　...<br>　　end<br>　　与Pascal语言不同, end不需要与begin配对, 只需要在函数结束后打个end就可以了.<br>　　本例函数的作用是已知直角三角形直角边, 求斜边长度. 参数a,b分别表示直角边长,<br>　　在函数内定义了local形变量用于存储斜边的平方. 与C语言相同, 定义在函数内的代<br>　　码不会被直接执行, 只有主程序调用时才会被执行.<br>　　local表示定义一个局部变量, 如果不加local刚表示c2为一个全局变量, local的作用域<br>　　是在最里层的end和其配对的关键字之间, 如if ... end, while ... end等。全局变量的<br>　　作用域是整个程序。<br>　　<br>　　<strong>2. 循环语句</strong><br>　　例e03.lua<br>　　-- Loops<br>　　for i=1,5 do<br>　　print("i is now " .. i)<br>　　end<br>　　<br>　　运行结果<br>　　i is now 1<br>　　i is now 2<br>　　i is now 3<br>　　i is now 4<br>　　i is now 5<br>　　<br>　　程序说明<br>　　这里偶们用到了for语句<br>　　for 变量 = 参数1, 参数2, 参数3 do<br>　　循环体<br>　　end<br>　　变量将以参数3为步长, 由参数1变化到参数2<br>　　例如:<br>　　for i=1,f(x) do print(i) end<br>　　for i=10,1,-1 do print(i) end<br>　　<br>　　这里print("i is now " .. i)中，偶们用到了..，这是用来连接两个字符串的，<br>　　偶在(1)的试试看中提到的，不知道你们答对了没有。<br>　　虽然这里i是一个整型量，Lua在处理的时候会自动转成字符串型，不需偶们费心。<br>　　<br>　　<strong>3. 条件分支语句</strong><br>　　例e04.lua<br>　　-- Loops and conditionals<br>　　for i=1,5 do<br>　　print(&#8220;i is now &#8220; .. i)<br>　　　　　if i &lt; 2 then<br>　　　　　print(&#8220;small&#8221;)<br>　　　　　elseif i &lt; 4 then<br>　　　　　print(&#8220;medium&#8221;)<br>　　　　　else<br>　　　　　print(&#8220;big&#8221;)<br>　　　　　end<br>　　end<br>　　<br>　　运行结果<br>　　i is now 1<br>　　small<br>　　i is now 2<br>　　medium<br>　　i is now 3<br>　　medium<br>　　i is now 4<br>　　big<br>　　i is now 5<br>　　big<br>　　<br>　　程序说明<br>　　if else用法比较简单, 类似于C语言, 不过此处需要注意的是整个if只需要一个end,<br>　　哪怕用了多个elseif, 也是一个end.<br>　　例如<br>　　　　if op == "+" then<br>　　　　　r = a + b<br>　　　　elseif op == "-" then<br>　　　　　r = a - b<br>　　　　elseif op == "*" then<br>　　　　　r = a*b<br>　　　　elseif op == "/" then<br>　　　　　r = a/b<br>　　　　else<br>　　　　　error("invalid operation")<br>　　　　end<br>　　<br>　　<br>　　<strong>4.试试看</strong><br>　　Lua中除了for循环以外, 还支持多种循环, 请用while...do和repeat...until改写本文中的for程序 <br><br><font size=6><strong>三.Lua数据结构</strong></font><br><br>　<strong>1.简介</strong><br>　　Lua语言只有一种基本数据结构, 那就是table, 所有其他数据结构如数组啦,<br>　　类啦, 都可以由table实现.<br>　　例e05.lua<br>　　-- Arrays<br>　　myData = {}<br>　　myData[0] = &#8220;foo&#8221;<br>　　myData[1] = 42<br>　　<br>　　-- Hash tables<br>　　myData[&#8220;bar&#8221;] = &#8220;baz&#8221;<br>　　<br>　　-- Iterate through the<br>　　-- structure<br>　　for key, value in myData do<br>　　print(key .. &#8220;=&#8220; .. value)<br>　　end<br>　　<br>　　输出结果<br>　　0=foo<br>　　1=42<br>　　bar=baz<br>　　<br>　　程序说明<br>　　首先定义了一个table myData={}, 然后用数字作为下标赋了两个值给它. 这种<br>　　定义方法类似于C中的数组, 但与数组不同的是, 每个数组元素不需要为相同类型,<br>　　就像本例中一个为整型, 一个为字符串.<br>　　<br>　　程序第二部分, 以字符串做为下标, 又向table内增加了一个元素. 这种table非常<br>　　像STL里面的map. table下标可以为Lua所支持的任意基本类型, 除了nil值以外.<br>　　<br>　　Lua对Table占用内存的处理是自动的, 如下面这段代码<br>　　　　a = {}<br>　　　　a["x"] = 10<br>　　　　b = a　　　-- `b' refers to the same table as `a'<br>　　　　print(b["x"])　--&gt; 10<br>　　　　b["x"] = 20<br>　　　　print(a["x"])　--&gt; 20<br>　　　　a = nil　　-- now only `b' still refers to the table<br>　　　　b = nil　　-- now there are no references left to the table<br>　　b和a都指向相同的table, 只占用一块内存, 当执行到a = nil时, b仍然指向table,<br>　　而当执行到b=nil时, 因为没有指向table的变量了, 所以Lua会自动释放table所占内存<br>　　<br>　　<strong>3.Table的嵌套</strong><br>　　Table的使用还可以嵌套，如下例<br>　　例e06.lua<br>　　-- Table &#8216;constructor&#8217;<br>　　myPolygon = {<br>　　color=&#8220;blue&#8221;,<br>　　thickness=2,<br>　　npoints=4;<br>　　{x=0,　 y=0},<br>　　{x=-10, y=0},<br>　　{x=-5,　y=4},<br>　　{x=0,　 y=4}<br>　　}<br>　　<br>　　-- Print the color<br>　　print(myPolygon[&#8220;color&#8221;])<br>　　<br>　　-- Print it again using dot<br>　　-- notation<br>　　print(myPolygon.color)<br>　　<br>　　-- The points are accessible<br>　　-- in myPolygon[1] to myPolygon[4]<br>　　<br>　　-- Print the second point&#8217;s x<br>　　-- coordinate<br>　　print(myPolygon[2].x)<br>　　<br>　　<strong>程序说明</strong><br>　　首先建立一个table, 与上一例不同的是，在table的constructor里面有{x=0,y=0},<br>　　这是什么意思呢？ 这其实就是一个小table, 定义在了大table之内, 小table的<br>　　table名省略了.<br>　　最后一行myPolygon[2].x，就是大table里面小table的访问方式.<br>　　 <br><strong><font size=6>四.函数的调用</font></strong><br><br>　<strong>1.不定参数</strong><br>　　例e07.lua<br>　　-- Functions can take a<br>　　-- variable number of<br>　　-- arguments.<!--dvnews_ad_begin--><br>　　function funky_print (...)<br>　　for i=1, arg.n do<br>　　print("FuNkY: " .. arg[i])<br>　　end<br>　　end<br>　　<br>　　funky_print("one", "two")<br>　　<br>　　运行结果<br>　　FuNkY: one<br>　　FuNkY: two<br>　　<br>　　程序说明<br>　　* 如果以...为参数, 则表示参数的数量不定.<br>　　* 参数将会自动存储到一个叫arg的table中.<br>　　* arg.n中存放参数的个数. arg[]加下标就可以遍历所有的参数.<br>　　<br>　　<br>　　<strong>2.以table做为参数</strong><br>　　例e08.lua<br>　　-- Functions with table<br>　　-- parameters<br>　　function print_contents(t)<br>　　for k,v in t do<br>　　print(k .. "=" .. v)<br>　　end<br>　　end<br>　　print_contents{x=10, y=20}<br>　　<br>　　运行结果<br>　　x=10<br>　　y=20<br>　　<br>　　程序说明<br>　　* print_contents{x=10, y=20}这句参数没加圆括号, 因为以单个table为参数的时候, 不需要加圆括号<br>　　* for k,v in t do 这个语句是对table中的所有值遍历, k中存放名称, v中存放值<br>　　<br>　　<br>　　<strong>3.把Lua变成类似XML的数据描述语言</strong><br>　　例e09.lua<br>　　function contact(t)<br>　　-- add the contact &#8216;t&#8217;, which is<br>　　-- stored as a table, to a database<br>　　end<br>　　<br>　　contact {<br>　　name = "Game Developer",<br>　　email = "hack@ogdev.net",<br>　　url = "http://www.ogdev.net",<br>　　quote = [[<br>　　There are<br>　　10 types of people<br>　　who can understand binary.]]<br>　　}<br>　　<br>　　contact {<br>　　-- some other contact<br>　　}<br>　　<br>　　程序说明<br>　　* 把function和table结合, 可以使Lua成为一种类似XML的数据描述语言<br>　　* e09中contact{...}, 是一种函数的调用方法, 不要弄混了<br>　　* [[...]]是表示多行字符串的方法<br>　　* 当使用C API时此种方式的优势更明显, 其中contact{..}部分可以另外存成一配置文件<br>　　<br>　　<strong>4.试试看</strong><br>　　想想看哪些地方可以用到例e09中提到的配置方法呢？<br>　　<br><br><font size=6><strong>五.Lua与C的交互</strong></font><br><br>　<strong>1.简介</strong><br>　　<br>　　Lua与C/C++结合是很紧密的, Lua与C++交互是建立在Lua与C的基础上的, 所<br>　　以偶先从Lua与C讲起.<br>　　<br>　　正如第一讲所说, 运行Lua程序或者说调用Lua主要有两种方式:<!--dvnews_ad_begin--><br>　　* 通过命令行执行"Lua"命令<br>　　* 通过Lua的C库<br>　　虽然此前偶们一直用第一种方式, 但偶要告诉你, 通过Lua的C库执行才是游戏中<br>　　常用的方式.<br>　　<br>　　<strong>2.Lua的C库</strong><br>　　<br>　　Lua的C库可以做为Shared Library调用, 但一般开发游戏时会把Lua的所有源程序<br>　　都包含在内, 并不把Lua编译成共享库的形式. 因为Lua程序只有100多K, 而且几乎<br>　　可以在任何编译器下Clean Compile. 带Lua源程序的另一个好处时, 可以随时对Lua<br>　　本身进行扩充, 增加偶们所需的功能.<br>　　<br>　　Lua的C库提供一系列API:<br>　　* 管理全局变量<br>　　* 管理tables<br>　　* 调用函数<br>　　* 定义新函数, 这也可以完全由C实现<br>　　* 垃圾收集器Garbage collector, 虽然Lua可以自动进行, 但往往不是立即执行的,<br>　　　所以对实时性要求比较高的程序, 会自己调用垃圾收集器<br>　　* 载入并执行Lua程序, 这也可以由Lua自身实现<br>　　* 任何Lua可以实现的功能, 都可以通过Lua的C API实现, 这对于优化程序的运行速度<br>　　　有帮助. 经常调用的共用的Lua程序片断可以转成C程序, 以提高效率. 连Lua都是C写的<br>　　　还有什么C不能实现呢?<br>　　<br>　　<strong>3.Lua与C集成的例子</strong><br>　　例e10.c<br>　　/* A simple Lua interpreter. */<br>　　#include <stdio.h><br>　　#include <lua.h><br>　　int main(int argc, char *argv[]) {<br>　　char line[BUFSIZ];<br>　　lua_State *L = lua_open(0);<br>　　while (fgets(line, sizeof(line), stdin) != 0)<br>　　lua_dostring(L, line);<br>　　lua_close(L);<br>　　return 0;<br>　　}<br>　　<br>　　编译<br>　　Linux/Cygwin<br>　　* 先编译Lua, 并把头文件放入include路径<br>　　* gcc e10.c -llua -llualib -o e10<br>　　<br>　　VC6/VC2003<br>　　* 先编译Lua, 在Option中设置头文件和库文件路径<br>　　* 新建工程,在工程配置中加入附加库lua.lib和lualib.lib<br>　　* 编译成exe<br>　　<br>　　运行结果<br>　　本程序的功能是实现一个Lua解释器, 输入的每行字符都会被解释成Lua并执行.<br>　　<br>　　程序说明<br>　　* #include <lua.h>包含lua头文件, 然后才可以使用API<br>　　* lua_State *L = lua_open(0) 打开一个Lua执行器<br>　　* fgets(line, sizeof(line), stdin) 从标准输入里读入一行<br>　　* lua_dostring(L, line) 执行此行<br>　　* lua_close(L) 关闭Lua执行器<br>　　<br>　　<br>　　例e11.c<br>　　/* Another simple Lua interpreter. */<br>　　#include <stdio.h><br>　　#include <lua.h><br>　　#include <lualib.h><br>　　int main(int argc, char *argv[]) {<br>　　char line[BUFSIZ];<br>　　lua_State *L = lua_open(0);<br>　　lua_baselibopen(L);<br>　　lua_iolibopen(L);<br>　　lua_strlibopen(L);<br>　　lua_mathlibopen(L);<br>　　while (fgets(line, sizeof(line), stdin) != 0)<br>　　lua_dostring(L, line);<br>　　lua_close(L);<br>　　return 0;<br>　　}<br>　　<br>　　运行结果<br>　　本程序的功能是实现一个Lua解释器, 输入的每行字符都会被解释成Lua并执行.<br>　　与上例不同的是, 本例调用了Lua的一些标准库.<br>　　<br>　　程序说明<br>　　* #include <lualib.h>包含Lua的标准库<br>　　* 以下这几行是用来读入Lua的一些库, 这样偶们的Lua程序就可以有更多的功能.<br>　　lua_baselibopen(L);<br>　　lua_iolibopen(L);<br>　　lua_strlibopen(L);<br>　　lua_mathlibopen(L);<br>　　<br>　　<strong>4.试试看</strong><br>　　把上面两个小例子在你熟悉的编译器中编译执行, 并试试能否与Lua源码树一起编译<br><br><strong><font color=#000000 size=6>六.C/C++中用Lua函数<br></font></strong><br><strong>1.简介<br></strong>　　偶们这次主要说说怎么由Lua定义函数, 然后在C或者C++中调用. 这里偶们<br>　　暂不涉及C++的对象问题, 只讨论调用函数的参数, 返回值和全局变量的使用.<!--dvnews_ad_begin--><br><br>　　<strong>2.程序</strong><br>　　这里偶们在e12.lua里先定义一个简单的add(), x,y为加法的两个参数,<br>　　return 直接返回相加后的结果.<br>　　<br>　　例e12.lua<br>　　-- add two numbers<br>　　function add ( x, y )<br>　　return x + y<br>　　end<br>　　<br>　　在前一次里, 偶们说到 lua_dofile() 可以直接在C中执行lua文件. 因为偶们<br>　　这个程序里只定义了一个add()函数, 所以程序执行后并不直接结果, 效果相当<br>　　于在C中定义了一个函数一样.<br>　　<br>　　Lua的函数可以有多个参数, 也可以有多个返回值, 这都是由栈(stack)实现的.<br>　　需要调用一个函数时, 就把这个函数压入栈, 然后顺序压入所有参数, 然后用<br>　　lua_call()调用这个函数. 函数返回后, 返回值也是存放在栈中. 这个过程和<br>　　汇编执行函数调用的过程是一样的.<br>　　<br>　　例e13.cpp 是一个调用上面的Lua函数的例子<br>　　#include <stdio.h><br>　　<br>　　extern "C" { // 这是个C++程序, 所以要extern "C",<br>　　　　 // 因为lua的头文件都是C格式的<br>　　#include "lua.h"<br>　　#include "lualib.h"<br>　　#include "lauxlib.h"<br>　　}<br>　　<br>　　/* the Lua interpreter */<br>　　lua_State* L;<br>　　<br>　　int luaadd ( int x, int y )<br>　　{<br>　　int sum;<br>　　<br>　　/* the function name */<br>　　lua_getglobal(L, "add");<br>　　<br>　　/* the first argument */<br>　　lua_pushnumber(L, x);<br>　　<br>　　/* the second argument */<br>　　lua_pushnumber(L, y);<br>　　<br>　　/* call the function with 2<br>　　　 arguments, return 1 result */<br>　　lua_call(L, 2, 1);<br>　　<br>　　/* get the result */<br>　　sum = (int)lua_tonumber(L, -1);<br>　　lua_pop(L, 1);<br>　　<br>　　return sum;<br>　　}<br>　　<br>　　int main ( int argc, char *argv[] )<br>　　{<br>　　int sum;<br>　　<br>　　/* initialize Lua */<br>　　L = lua_open();<br>　　<br>　　/* load Lua base libraries */<br>　　lua_baselibopen(L);<br>　　<br>　　/* load the script */<br>　　lua_dofile(L, "e12.lua");<br>　　<br>　　/* call the add function */<br>　　sum = luaadd( 10, 15 );<br>　　<br>　　/* print the result */<br>　　printf( "The sum is %d\n", sum );<br>　　<br>　　/* cleanup Lua */<br>　　lua_close(L);<br>　　<br>　　return 0;<br>　　}<br>　　<br>　　程序说明:<br>　　main中过程偶们上次已经说过了, 所以这次只说说luaadd的过程<br>　　* 首先用lua_getglobal()把add函数压栈<br>　　* 然后用lua_pushnumber()依次把x,y压栈<br>　　* 然后调用lua_call(), 并且告诉程序偶们有两个参数一个返回值<br>　　* 接着偶们从栈顶取回返回值, 用lua_tonumber()<br>　　* 最后偶们用lua_pop()把返回值清掉<br>　　<br>　　运行结果:<br>　　The sum is 25<br>　　<br>　　编译方法<br>　　Linux下把程序存成e13.cpp<br>　　g++ e13.cpp -llua -llualib -o e13<br>　　./e13<br>　　<br>　　VC下编译方法<br>　　* 首先建立一个空的Win32 Console Application Project<br>　　* 把e13.cpp加入工程中<br>　　* 点project setting,然后设置link选项, 再加上lua.lib lualib.lib两个额外的库<br>　　* 最后编译<br>　　<br>　　建立好的project可以在这里下载<br>　　VC http://tonyandpaige.com/tutorials/luaadd.zip<br>　　Linux http://tonyandpaige.com/tutorials/luaadd.tar.gz<br>　　<br>　　<strong>3.全局变量</strong><br>　　上面偶们用到了lua_getglobal()但并没有详细讲, 这里偶们再举两个小例子来说下全局变量<br>　　lua_getglobal()的作用就是把lua中全局变量的值压入栈<br>　　lua_getglobal(L, "z");<br>　　z = (int)lua_tonumber(L, 1);<br>　　lua_pop(L, 1);<br>　　假设Lua程序中定义了一个全局变量z, 这段小程序就是把z的值取出放入C的变量z中.<br>　　<br>　　另外Lua中还有一个对应的函数lua_setglobal(), 作用是用栈顶的值填充指定的全局变量<br>　　lua_pushnumber(L, 10);<br>　　lua_setglobal(L, "z");<br>　　例如这段小程序就是把lua中的全局变量z设为10, 如果lua中未定义z的话, 就会自动创建一个<br>　　全局变量z并设为10.<br>　　<br>　　<strong>4.试试看</strong><br>　　自己写个函数用C/C++来调用下试试<br><br><font size=6><strong>七.调用C/C++函数</strong></font><br><br><strong>1.前言<br></strong>　　上次偶说到从C/C++中调用Lua的函数, 然后就有朋友问从Lua中如何调用C/C++的<br>　　函数, 所以偶们这次就来说说这个问题. 首先偶们会在C++中建立一个函数, 然后<!--dvnews_ad_begin--><br>　　告知Lua有这个函数, 最后再执行它. 另外, 由于函数不是在Lua中定义的, 所以<br>　　无法确定函数的正确性, 可能在调用过程中会出错, 因此偶们还会说说Lua出错处<br>　　理的问题.<br>　　<br>　　<strong>2.Lua中调用C函数</strong><br>　　在lua中是以函数指针的形式调用函数, 并且所有的函数指针都必须满足如下此种<br>　　类型:<br>　　typedef int (*lua_CFunction) (lua_State *L);<br>　　<br>　　也就是说, 偶们在C++中定义函数时必须以lua_State为参数, 以int为返回值才能<br>　　被Lua所调用. 但是不要忘记了, 偶们的lua_State是支持栈的, 所以通过栈可以<br>　　传递无穷个参数, 大小只受内存大小限制. 而返回的int值也只是指返回值的个数<br>　　真正的返回值都存储在lua_State的栈中. 偶们通常的做法是做一个wrapper, 把<br>　　所有需要调用的函数都wrap一下, 这样就可以调用任意的函数了.<br>　　<br>　　下面这个例子是一个C++的average()函数, 它将展示如何用多个参数并返回多个值<br>　　<br>　　例e14.cpp<br>　　#include <stdio.h><br>　　<br>　　extern "C" {<br>　　#include "lua.h"<br>　　#include "lualib.h"<br>　　#include "lauxlib.h"<br>　　}<br>　　<br>　　/* the Lua interpreter */<br>　　lua_State* L;<br>　　<br>　　static int average(lua_State *L)<br>　　{<br>　　/* get number of arguments */<br>　　int n = lua_gettop(L);<br>　　double sum = 0;<br>　　int i;<br>　　<br>　　/* loop through each argument */<br>　　for (i = 1; i &lt;= n; i++)<br>　　{<br>　　/* total the arguments */<br>　　sum += lua_tonumber(L, i);<br>　　}<br>　　<br>　　/* push the average */<br>　　lua_pushnumber(L, sum / n);<br>　　<br>　　/* push the sum */<br>　　lua_pushnumber(L, sum);<br>　　<br>　　/* return the number of results */<br>　　return 2;<br>　　}<br>　　<br>　　int main ( int argc, char *argv[] )<br>　　{<br>　　/* initialize Lua */<br>　　L = lua_open();<br>　　<br>　　/* load Lua base libraries */<br>　　lua_baselibopen(L);<br>　　<br>　　/* register our function */<br>　　lua_register(L, "average", average);<br>　　<br>　　/* run the script */<br>　　lua_dofile(L, "e15.lua");<br>　　<br>　　/* cleanup Lua */<br>　　lua_close(L);<br>　　<br>　　return 0;<br>　　}<br>　　<br>　　例e15.lua<br>　　-- call a C++ function<br>　　<br>　　avg, sum = average(10, 20, 30, 40, 50)<br>　　<br>　　print("The average is ", avg)<br>　　print("The sum is ", sum)<br>　　<br>　　<br>　　程序说明:<br>　　* lua_gettop()的作用是返回栈顶元素的序号. 由于Lua的栈是从1开始编号的,<br>　　　所以栈顶元素的序号也相当于栈中的元素个数. 在这里, 栈中元素的个数就<br>　　　是传入的参数个数.<br>　　* for循环计算所有传入参数的总和. 这里用到了数值转换lua_tonumber().<br>　　* 然后偶们用lua_pushnumber()把平均值和总和push到栈中.<br>　　* 最后, 偶们返回2, 表示有两个返回值.<br>　　* 偶们虽然在C++中定义了average()函数, 但偶们的Lua程序并不知道, 所以需<br>　　　要在main函数中加入<br>　　<br>　　　 /* register our function */<br>　　lua_register(L, "average", average);<br>　　<br>　　　这两行的作用就是告诉e15.lua有average()这样一个函数.<br>　　* 这个程序可以存成cpp也可以存成c, 如果以.c为扩展名就不需要加extern "C"<br>　　<br>　　编译的方法偶们上次说过了, 方法相同.<br>　　e15.lua执行的方法只能用上例中的C++中执行, 而不能用命令行方式执行.<br>　　<br>　　<strong>3.错误处理</strong><br>　　在上例中, 偶们没有对传入的参数是否为数字进行检测, 这样做不好. 所以这里偶<br>　　们再加上错误处理的片断.<br>　　<br>　　把这段加在for循环之内:<br>　　if (!lua_isnumber(L, i)) {<br>　　lua_pushstring(L, "Incorrect argument to 'average'");<br>　　lua_error(L);<br>　　}<br>　　这段的作用就是检测传入的是否为数字.<br>　　<br>　　加上这段之后, 偶们debug的时候就会简单许多. 对于结合两种语言的编程, 它们之<br>　　间传递数据的正确性检测是非常重要的.<br>　　<br>　　这里有别人写好的例子:<br>　　VC的 http://tonyandpaige.com/tutorials/luaavg.zip<br>　　Linux的 http://tonyandpaige.com/tutorials/luaavg.tar.gz<br>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113180.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 22:38 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113180.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转贴】Lua 编程技巧 </title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113179.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 14:36:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113179.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113179.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113179.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113179.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113179.html</trackback:ping><description><![CDATA[<div class=page><a href="http://blog.codingnow.com/cloud/Lua5"><u><font color=#0000ff>Lua</font></u></a> 的 5.1 版本已经正式发布。现在，我们应该把全部讨论放在这个版本上。<br><br><img title=Hot! height=11 alt=Hot! hspace=4 src="http://blog.codingnow.com/cloud//images/idea.gif" width=7 border=0><strong>应该尽量使用 local 变量而非 global 变量</strong>。这是 <a href="http://blog.codingnow.com/cloud/Lua5"><u><font color=#0000ff>Lua</font></u></a> 初学者最容易犯的错误。global 变量实际上是放在一张全局的 table 里的。global 变量实际上是利用一个 string (变量名作 key) 去访问这个 table 。虽然<a href="http://blog.codingnow.com/2005/10/lua_table.html" target=_blank><img title=在新窗口中打开 height=11 alt=[InterWiki] hspace=4 src="http://blog.codingnow.com/cloud//images/inter.gif" width=11 border=0></a><a href="http://blog.codingnow.com/2005/10/lua_table.html"><u><font color=#0000ff>Lua5 的 table 效率很高</font></u></a> ，但是相对于 local 变量，依然有很大的效率损失。local 变量是直接通过 <a href="http://blog.codingnow.com/cloud/Lua5"><u><font color=#0000ff>Lua</font></u></a> 的堆栈访问的。有些 global 变量的访问是不经意的，比如我们有双重循环操作一个迭代的 table：<br>
<pre class=code><span class=kw1>for</span> k1,v1 <span class=kw1>in</span><span class=kw1>pairs</span><span class=br0>(</span>tbl<span class=br0>)</span><span class=kw1>do</span><span class=kw1>for</span> k2,v2 <span class=kw1>in</span><span class=kw1>pairs</span><span class=br0>(</span>v1<span class=br0>)</span><span class=kw1>do</span>
...
<span class=kw1>end</span>
end</pre>
<br><br>这里，pairs 其实是一个全局变量应用的函数。如果我们这样做：<br>
<pre class=code><span class=kw1>do</span><span class=kw1>local</span><span class=kw1>pairs</span>=pairs
<span class=kw1>for</span> k1,v1 <span class=kw1>in</span><span class=kw1>pairs</span><span class=br0>(</span>tbl<span class=br0>)</span><span class=kw1>do</span><span class=kw1>for</span> k2,v2 <span class=kw1>in</span><span class=kw1>pairs</span><span class=br0>(</span>v1<span class=br0>)</span><span class=kw1>do</span>
...
<span class=kw1>end</span><span class=kw1>end</span>
end</pre>
<br><br>效率会稍微提高一些。如果是单层循环，这样做就没有意义。因为 for ... in 循环中的 pairs 这个函数只会被调用一次，而不是每次循环都去调。我们的原则其实是，被多次读取的 global 变量，都应该提取出来放到 local 变量中。<br><br><img title=Hot! height=11 alt=Hot! hspace=4 src="http://blog.codingnow.com/cloud//images/idea.gif" width=7 border=0><strong>警惕临时变量</strong> 字符串的连接操作，会产生新的对象。这是由 lua 本身的 string 管理机制导致的。lua 在 VM 内对相同的 string 永远只保留一份唯一 copy ，这样，所有字符串比较就可以简化为地址比较。这也是 lua 的 table 工作很快的原因之一。这种 string 管理的策略，跟 java 等一样，所以跟 java 一样，应该尽量避免在循环内不断的连接字符串，比如 a = a..x 这样。每次运行，都很可能会生成一份新的 copy 。<br><br>同样，记住，每次构造一份 table 都会多一份 table 的 copy 。比如在 lua 里，把平面坐标封装成 { x, y } 用于参数传递，就需要考虑这个问题。每次你想构造一个坐标对象传递给一个函数，{ 10,20 }&nbsp;&nbsp;这样明确的写出，都会构造一个新的 table 出来。要么，我们想办法考虑 table 的重用；要么，干脆用 x,y 两个参数传递坐标。<br><br>同样需要注意的是以 function foo (...) 这种方式定义函数， ... 这种不定参数，每次调用的时候都会被定义出一个 table 存放不定数量的参数。<br><br>这些临时构造的对象往往要到 gc 的时候才被回收，过于频繁的 gc 有时候正是效率瓶颈。<br><br><img title=Hot! height=11 alt=Hot! hspace=4 src="http://blog.codingnow.com/cloud//images/idea.gif" width=7 border=0><strong>使用 closure 代替 table</strong> 上面提到封装坐标的问题。诚然，我们可以用 { x=1,y=2 } 这样封装一个坐标。不过还有一个方法可供选择。它稍微轻量一点。<br><br>
<pre class=code><span class=kw1>function</span> point <span class=br0>(</span>x,y<span class=br0>)</span><span class=kw1>return</span><span class=kw1>function</span><span class=br0>(</span><span class=br0>)</span><span class=kw1>return</span> x,y <span class=kw1>end</span>
end
&nbsp;
<span class=co1>-- 使用范例</span>
p=point<span class=br0>(</span><span class=nu0>1</span>,<span class=nu0>2</span><span class=br0>)</span><span class=kw1>print</span><span class=br0>(</span>p<span class=br0>(</span><span class=br0>)</span><span class=br0>)</span><span class=co1>-- 输出 1	 2 </span>
&nbsp;</pre>
<br><br>如果你愿意，还可以做的复杂一点：<br>
<pre class=code><span class=kw1>function</span> point <span class=br0>(</span>x,y<span class=br0>)</span><span class=kw1>return</span><span class=kw1>function</span><span class=br0>(</span>idx<span class=br0>)</span><span class=kw1>if</span> idx==<span class=st0>"x"</span><span class=kw1>then</span><span class=kw1>return</span> x
<span class=kw1>elseif</span> idx==<span class=st0>"y"</span><span class=kw1>then</span><span class=kw1>return</span> y
<span class=kw1>else</span><span class=kw1>return</span> x,y <span class=kw1>end</span><span class=kw1>end</span>
end
&nbsp;
<span class=co1>-- 使用范例</span>
p=point<span class=br0>(</span><span class=nu0>1</span>,<span class=nu0>2</span><span class=br0>)</span><span class=kw1>print</span><span class=br0>(</span>p<span class=br0>(</span><span class=st0>"x"</span><span class=br0>)</span><span class=br0>)</span><span class=co1>-- 1</span><span class=kw1>print</span><span class=br0>(</span>p<span class=br0>(</span><span class=st0>"y"</span><span class=br0>)</span><span class=br0>)</span><span class=co1>-- 2 </span>
&nbsp;</pre>
<br><br>x,y 实际被存放在 closure 里，每次调用 function point 都有一份独立的 closure。当然，function 的 code 只有一份。<br><br><img title=Hot! height=11 alt=Hot! hspace=4 src="http://blog.codingnow.com/cloud//images/idea.gif" width=7 border=0><strong>设法减少从 C 向 Lua 传递字符串</strong> 字符串常量在 Lua VM 内部工作的非常快，但是一个从 C 向 lua vm 通过 lua_pushstring 之类的 api 传递进 VM 时，就需要掂量一下了。这至少包含一个再 hash 和匹配的过程。<a href="http://blog.codingnow.com/2006/01/_lua.html" target=_blank><img title=在新窗口中打开 height=11 alt=[InterWiki] hspace=4 src="http://blog.codingnow.com/cloud//images/inter.gif" width=11 border=0></a><a href="http://blog.codingnow.com/2006/01/_lua.html"><u><font color=#0000ff>我的 Blog 上的一篇文章讨论了这个问题</font></u></a>。<br><br><img title=Hot! height=11 alt=Hot! hspace=4 src="http://blog.codingnow.com/cloud//images/idea.gif" width=7 border=0><strong>lua 中的继承</strong> lua 中实现 OO ，虚表往往设置一个 metatable 并设置 __index ，而继承则用 metatable 的 __index 把虚表串起来。当类继承层次过多的时候，效率比较低，那么就可以用下面这个技巧。<br>
<pre class=code><span class=kw1>function</span> inherit<span class=br0>(</span>sub,super<span class=br0>)</span><span class=kw1>setmetatable</span><span class=br0>(</span>sub,
<span class=br0>{</span> __index=<span class=kw1>function</span><span class=br0>(</span>t,k<span class=br0>)</span><span class=kw1>local</span> ret=super<span class=br0>[</span>k<span class=br0>]</span>
sub<span class=br0>[</span>k<span class=br0>]</span>=ret
<span class=kw1>return</span> ret
<span class=kw1>end</span><span class=br0>}</span><span class=br0>)</span><span class=kw1>end</span></pre>
<br><br><img title=Hot! height=11 alt=Hot! hspace=4 src="http://blog.codingnow.com/cloud//images/idea.gif" width=7 border=0><strong>利用逻辑运算的短路效应</strong> lua 编程中，and or 跟 C 一样是有短路效应的，不过他们的返回值并非 bool 类型，而是表达式中的左值或者右值。我们常常利用这个特性来简化代码。<br>
<pre class=code><span class=kw1>function</span> foo<span class=br0>(</span>arg<span class=br0>)</span>
arg=arg <span class=kw1>or</span><span class=st0>"default"</span>
...
<span class=kw1>end</span></pre>
<br>利用 or 运算赋缺省值是最常用的技巧。上例中，如果 arg 为 nil ，arg 就会被赋值为 "default" 。但是这个技巧有个缺陷，当缺省值是 true 的时候会有点问题。<br>
<pre class=code>a=a <span class=kw1>or</span><span class=kw1>true</span><span class=co1>-- 错误的写法，当 a 明确写为 false 的时候，也会被改变成 true 。</span>
a= a ~= <span class=kw1>false</span><span class=co1>-- 正确的写法，当 a 为 nil 的时候，被赋值为 true ；而 false 则不变。 </span>
&nbsp;</pre>
<br><br>另外，巧妙使用 and or 还可以实现类似 C 语言中的 ?: 三元操作：<br>
<pre class=code><span class=kw1>function</span><span class=kw1>max</span><span class=br0>(</span>a,b<span class=br0>)</span><span class=kw1>return</span> a&gt;b <span class=kw1>and</span> a <span class=kw1>or</span> b
<span class=kw1>end</span></pre>
<br>上面这个函数可以返回 a 和 b 中较大的一个，其逻辑类似 C 语言中的 return (a&gt;b) ? a : b ;</div>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113179.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 22:36 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113179.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[原创]Ogre向导教程(1) </title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113178.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 14:32:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113178.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113178.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113178.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113178.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113178.html</trackback:ping><description><![CDATA[<p>我这个人记性不好，学过的东西老是爱忘，学得越多忘得越快，脑子和我可怜的硬盘一样容量比较小，所以我发现我不得不把有些东西记录下来。其实学一样东西关键在于多学多用，有道是书读百遍其意自现，对于我这种比较笨又没天赋的人来说可谓金玉良言了。<br>以上算前言吧，下边才是正文。<br><br>Ogre这个引擎的效率不知道实际应用起来如何，但是听说结构倒是比较好的。选择它来学习主要是因为它开源，而且是C++和Dx写的，关键还有资料比较多，国内研究的也比较多，也有一些教程，不过Ogre不断推出新版本，许多教程都有点过期了。要了解最新的使用方法还得看官方的教程。我也是直接看官方的教程，但是英文一般，每次打开大片英文页面看着的确比较迷糊，所以我打算把里面一些重要的关键部分节选出来以备参考，有时候可以快速的重温，比如这篇要介绍的如何配置Ogre，需要记吗？程序员记不了那么多啦，用的时候再查。当然Ogre也在持续更新，如果我个人还在持续学习使用Ogre，那么我也会持续更新这些教程的，如果你是Ogre的使用者记得来我的Blog：<a href="http://www.cppblog.com/singohgod"><font color=#1a8bc8>http://www.cppblog.com/singohgod</font></a>&nbsp;看看吧，希望能对大家有点帮助。<br><br>首先安装SDK，可以编译里面带的示例看看一些效果展示。编译源码就得下载源码吧，记得还要下一个Dependencies，解压到源码目录就可以了，编译应该能通过的，我这里没有遇到问题。<br><br>不要被繁多的目录和文件吓着了，其实运行Ogre程序只需要下列库和文件：<br>OGRE Libraries &amp; Files </p>
<ul>
    <li>OGRE libraries (OgreMain[_d].dll, OgrePlatform[_d].dll or libOgreMain.so, libOgrePlatform.so for linux).
    <li>plugins.cfg - Text file specifying the rendering libraries available to Ogre (ie DX9, OpenGL).
    <li>All the plugin libraries listed in plugins.cfg (you can remove items from plugins.cfg if you don't wish to use them).
    <li>resources.cfg - If using the ExampleApplication, a text file specifing paths to materials, textures, models, etc.
    <li>OgreCore.zip - Ensure resources.cfg has the proper path to this file if you plan to use the OGRE debug panel or profiler.
    <li>Other Resources used in your program (*.zip; *.png; *.particle; *.mesh; ...). </li>
</ul>
<p>还需要其他的第三方库：<br>These are required: </p>
<ul>
    <li>Zlib: zlib1.dll; libz.so (debian: zlib1g, zlib1g-dev)
    <li>DevIL: devil.dll, ilu.dll, ilut.dll; libIL.so, libILU.so (debian: libdevil1, libdevil-dev) </li>
</ul>
<p>These are optional: </p>
<ul>
    <li>CEGUI: OgreGUIRenderer[_d].dll, CEGUIBase[_d].dll, CEGUITaharezLook[_d].dll, CEGUIWindowsLook[_d].dll, xerces-c_2_5_0.dll
    <li>CEGUI: libCEGUIBase.so, libCEGUIOgreRenderer.so, libxerces-c.so (debian: libcegui-mk2-0, libcegui-mk2-dev, libxerces26, libxerces26-dev)
    <li>Cg: cg.dll; libCg.so (debian: nvidia-cg-toolkit)
    <li>OpenEXR: openexr.dll??; (debian: libopenexr-dev libopenexr2 )
    <li>ReferenceApp: ReferenceAppLayer.dll </li>
</ul>
<p>不同的编译器还需要有：<br>Extras for Microsoft Visual C++ 6 (SP3+) </p>
<ul>
    <li>stlport_vc6[_stldebug]46.dll
    <li>msvcp60[D].dll
    <li>msvcrt[D].dll </li>
</ul>
<dl>
<dt>Extras for Microsoft Visual C++.Net 2002 </dt></dl>
<ul>
    <li>stlport_vc7[_stldebug]46.dll
    <li>msvcp70[d].dll
    <li>msvcr70[d].dll </li>
</ul>
<dl>
<dt>Extras for Microsoft Visual C++.Net 2003 </dt></dl>
<ul>
    <li>msvcp71[d].dll
    <li>msvcr71[d].dll </li>
</ul>
<dl>
<dt>Extras for Mingw + STLPort </dt></dl>
<ul>
    <li>libstlport[stlg].5.0.dll
    <li>mingwm10.dll </li>
</ul>
<p><br>设置环境变量：<br>If you downloaded and installed the precompiled OGRE SDK, you should already have an environment variable called 'OGRE_HOME' registered already, pointing at the folder where you installed. If it isn't there you probably installed under a different user, so define OGRE_HOME manually </p>
<li>If you downloaded the source distribution, you should register a new environment variable OGRE_SRC pointing at the 'ogrenew' folder from the OGRE source
<p>Ogre源码项目的目录结构：<br>work_dir<br>&nbsp;&nbsp;&nbsp; include<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *.h<br>&nbsp;&nbsp;&nbsp; src<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *.cpp<br>&nbsp;&nbsp;&nbsp; scripts<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *.vcproj<br><br>新建项目也依据这个结构，你的项目应该有这些文件夹：'bin', 'include', 'media', 'testsolution', 'scripts', and 'src'<br><br>修改新项目的属性：<br>Debugging&nbsp;: Working Directory&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = ..\bin\Debug<br>C/C++&nbsp;: Preprocessor&nbsp;: Preprocessor Definitions += _STLP_DEBUG (only in Debug mode, not needed for .Net 2003 and 2005)<br>C/C++&nbsp;: Code Generation&nbsp;: Use runtime library = Multithreaded Debug DLL (Multithreaded DLL in Release)<br>Linker&nbsp;: General&nbsp;: Output File&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = ..\bin\Debug\[appname].exe<br>Linker&nbsp;: Input&nbsp;: Additional Dependencies&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; += OgreMain_d.lib (OgreMain.lib in Release)<br><br>如果你是安装SDK: </p>
<pre>C/C++&nbsp;: General&nbsp;: Additional Include Directories 	 = ..\include;$(OGRE_HOME)\include;$(OGRE_HOME)\samples\include
Linker&nbsp;: General&nbsp;: Additional Library Directories         = $(OGRE_HOME)\lib
</pre>
<p>如果你是编译源码: </p>
<pre>C/C++&nbsp;: General&nbsp;: Additional Include Directories 	 = ..\include;$(OGRE_SRC)\OgreMain\include;$(OGRE_SRC)\Samples\Common\Include
Linker&nbsp;: General&nbsp;: Additional Library Directories         = $(OGRE_SRC)\OgreMain\Lib\Debug<br><br><font face="Times New Roman">这些设置好以后你就可以新建一个SampleApp.cpp文件，然后拷贝如下代码：<br><br></font><br><br><br></pre>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">ExampleApplication.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Declare&nbsp;a&nbsp;subclass&nbsp;of&nbsp;the&nbsp;ExampleFrameListener&nbsp;class</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;MyListener&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;ExampleFrameListener<br><img id=Codehighlighter1_136_478_Open_Image onclick="this.style.display='none'; Codehighlighter1_136_478_Open_Text.style.display='none'; Codehighlighter1_136_478_Closed_Image.style.display='inline'; Codehighlighter1_136_478_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_136_478_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_136_478_Closed_Text.style.display='none'; Codehighlighter1_136_478_Open_Image.style.display='inline'; Codehighlighter1_136_478_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_136_478_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_136_478_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;MyListener(RenderWindow</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;win,&nbsp;Camera</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;cam)&nbsp;:&nbsp;ExampleFrameListener(win,&nbsp;cam)<br><img id=Codehighlighter1_230_236_Open_Image onclick="this.style.display='none'; Codehighlighter1_230_236_Open_Text.style.display='none'; Codehighlighter1_230_236_Closed_Image.style.display='inline'; Codehighlighter1_230_236_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_230_236_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_230_236_Closed_Text.style.display='none'; Codehighlighter1_230_236_Open_Image.style.display='inline'; Codehighlighter1_230_236_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_230_236_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_230_236_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;frameStarted(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;FrameEvent</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;evt)<br><img id=Codehighlighter1_288_358_Open_Image onclick="this.style.display='none'; Codehighlighter1_288_358_Open_Text.style.display='none'; Codehighlighter1_288_358_Closed_Image.style.display='inline'; Codehighlighter1_288_358_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_288_358_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_288_358_Closed_Text.style.display='none'; Codehighlighter1_288_358_Open_Image.style.display='inline'; Codehighlighter1_288_358_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_288_358_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_288_358_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;ExampleFrameListener::frameStarted(evt);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;frameEnded(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;FrameEvent</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;evt)<br><img id=Codehighlighter1_408_476_Open_Image onclick="this.style.display='none'; Codehighlighter1_408_476_Open_Text.style.display='none'; Codehighlighter1_408_476_Closed_Image.style.display='inline'; Codehighlighter1_408_476_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_408_476_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_408_476_Closed_Text.style.display='none'; Codehighlighter1_408_476_Open_Image.style.display='inline'; Codehighlighter1_408_476_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_408_476_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_408_476_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;ExampleFrameListener::frameEnded(evt);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Declare&nbsp;a&nbsp;subclass&nbsp;of&nbsp;the&nbsp;ExampleApplication&nbsp;class</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;SampleApp&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;ExampleApplication&nbsp;<br><img id=Codehighlighter1_581_926_Open_Image onclick="this.style.display='none'; Codehighlighter1_581_926_Open_Text.style.display='none'; Codehighlighter1_581_926_Closed_Image.style.display='inline'; Codehighlighter1_581_926_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_581_926_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_581_926_Closed_Text.style.display='none'; Codehighlighter1_581_926_Open_Image.style.display='inline'; Codehighlighter1_581_926_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_581_926_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_581_926_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;SampleApp()&nbsp;<br><img id=Codehighlighter1_610_615_Open_Image onclick="this.style.display='none'; Codehighlighter1_610_615_Open_Text.style.display='none'; Codehighlighter1_610_615_Closed_Image.style.display='inline'; Codehighlighter1_610_615_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_610_615_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_610_615_Closed_Text.style.display='none'; Codehighlighter1_610_615_Open_Image.style.display='inline'; Codehighlighter1_610_615_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_610_615_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_610_615_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">protected</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Define&nbsp;what&nbsp;is&nbsp;in&nbsp;the&nbsp;scene</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;createScene(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)<br><img id=Codehighlighter1_692_739_Open_Image onclick="this.style.display='none'; Codehighlighter1_692_739_Open_Text.style.display='none'; Codehighlighter1_692_739_Closed_Image.style.display='inline'; Codehighlighter1_692_739_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_692_739_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_692_739_Closed_Text.style.display='none'; Codehighlighter1_692_739_Open_Image.style.display='inline'; Codehighlighter1_692_739_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_692_739_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_692_739_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;put&nbsp;your&nbsp;scene&nbsp;creation&nbsp;in&nbsp;here</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Create&nbsp;new&nbsp;frame&nbsp;listener</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;createFrameListener(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)<br><img id=Codehighlighter1_813_924_Open_Image onclick="this.style.display='none'; Codehighlighter1_813_924_Open_Text.style.display='none'; Codehighlighter1_813_924_Closed_Image.style.display='inline'; Codehighlighter1_813_924_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_813_924_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_813_924_Closed_Text.style.display='none'; Codehighlighter1_813_924_Open_Image.style.display='inline'; Codehighlighter1_813_924_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_813_924_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_813_924_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mFrameListener&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;MyListener(mWindow,&nbsp;mCamera);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mRoot</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">addFrameListener(mFrameListener);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#ifdef&nbsp;__cplusplus<br><img id=Codehighlighter1_960_1724_Open_Image onclick="this.style.display='none'; Codehighlighter1_960_1724_Open_Text.style.display='none'; Codehighlighter1_960_1724_Closed_Image.style.display='inline'; Codehighlighter1_960_1724_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_960_1724_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_960_1724_Closed_Text.style.display='none'; Codehighlighter1_960_1724_Open_Image.style.display='inline'; Codehighlighter1_960_1724_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span style="COLOR: #0000ff">extern</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">C</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span id=Codehighlighter1_960_1724_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_960_1724_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">#if</span><span style="COLOR: #000000">&nbsp;OGRE_PLATFORM&nbsp;==&nbsp;OGRE_PLATFORM_WIN32&nbsp;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;WIN32_LEAN_AND_MEAN&nbsp;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">windows.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>INT&nbsp;WINAPI&nbsp;WinMain(HINSTANCE&nbsp;hInst,&nbsp;HINSTANCE,&nbsp;LPSTR&nbsp;strCmdLine,&nbsp;INT)&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">#else</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">**</span><span style="COLOR: #000000">argv)&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000"><br><img id=Codehighlighter1_1182_1702_Open_Image onclick="this.style.display='none'; Codehighlighter1_1182_1702_Open_Text.style.display='none'; Codehighlighter1_1182_1702_Closed_Image.style.display='inline'; Codehighlighter1_1182_1702_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_1182_1702_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1182_1702_Closed_Text.style.display='none'; Codehighlighter1_1182_1702_Open_Image.style.display='inline'; Codehighlighter1_1182_1702_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top></span><span id=Codehighlighter1_1182_1702_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_1182_1702_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Instantiate&nbsp;our&nbsp;subclass</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;SampleApp&nbsp;myApp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img id=Codehighlighter1_1246_1352_Open_Image onclick="this.style.display='none'; Codehighlighter1_1246_1352_Open_Text.style.display='none'; Codehighlighter1_1246_1352_Closed_Image.style.display='inline'; Codehighlighter1_1246_1352_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_1246_1352_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1246_1352_Closed_Text.style.display='none'; Codehighlighter1_1246_1352_Open_Image.style.display='inline'; Codehighlighter1_1246_1352_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000">&nbsp;</span><span id=Codehighlighter1_1246_1352_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_1246_1352_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;ExampleApplication&nbsp;provides&nbsp;a&nbsp;go&nbsp;method,&nbsp;which&nbsp;starts&nbsp;the&nbsp;rendering.</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myApp.go();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img id=Codehighlighter1_1385_1689_Open_Image onclick="this.style.display='none'; Codehighlighter1_1385_1689_Open_Text.style.display='none'; Codehighlighter1_1385_1689_Closed_Image.style.display='inline'; Codehighlighter1_1385_1689_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_1385_1689_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1385_1689_Closed_Text.style.display='none'; Codehighlighter1_1385_1689_Open_Image.style.display='inline'; Codehighlighter1_1385_1689_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000">&nbsp;(Ogre::Exception</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;e)&nbsp;</span><span id=Codehighlighter1_1385_1689_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_1385_1689_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">#if</span><span style="COLOR: #000000">&nbsp;OGRE_PLATFORM&nbsp;==&nbsp;OGRE_PLATFORM_WIN32&nbsp;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBoxA(NULL,&nbsp;e.getFullDescription().c_str(),&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">An&nbsp;exception&nbsp;has&nbsp;occured!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;MB_OK&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;MB_ICONERROR&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;MB_TASKMODAL);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">#else</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Exception:\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cerr&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;e.getFullDescription().c_str()&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>#ifdef&nbsp;__cplusplus<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<br>未完！ </li>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113178.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 22:32 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113178.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转载]3D图形技术常用技术一览 </title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113177.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 14:31:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113177.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113177.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113177.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113177.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113177.html</trackback:ping><description><![CDATA[<h4 class=TextColor1 id=subjcns!919190B17523684B!113 style="MARGIN-BOTTOM: 0px">3D图形技术常用技术一览</h4>
<div id=msgcns!919190B17523684B!113>
<div>一、场景管理相关的技术(scene manager th):</div>
<div>八叉树(octree) 、四叉树(quadtree)、二叉树(biniary space tree)、多叉树(n - tree)、入口技术(portal)、扩展入口(anti-portal) </div>
<div>&nbsp;</div>
<div>二、通用内核渲染管理技术(render manager)</div>
<div>队列(queue)、优先队列(deque)、链表(list)</div>
<div>&nbsp;</div>
<div>三、地形管理和绘制技术(terrain manager and render engine)</div>
<div>四叉树(quadtree，和scenemanager重合)、单位地形块管理(terrainChunk)、分块地形(mapTile)、</div>
<div>二元三角树(rometree)</div>
<div>&nbsp;</div>
<div>四、通用不可见面去除技术</div>
<div>背面剔除（back cull）、视口截头体剪裁（frustum）、遮挡面剔除(HBR)</div>
<div>&nbsp;</div>
<div>五、通用动画技术</div>
<div>关键帧动画(frame animate)、骨骼蒙皮动画（skeleton and skin mesh animate）、顶点动画(vertex animate)、纹理动画(textue animate)</div>
<div>&nbsp;</div>
<div>六、通用材质纹理技术:</div>
<div>单纹理(single texture)、多重纹理(multpile texture)、透明度纹理(alpha texture)、阴影贴图(shadow map)、光照贴图(light map)、法线贴图(normal texture)、高动态范围光照图(high dynamic range texture，用浮点纹理来模拟广泛的光照范围)、顶点置换图(displacement texture，利用法线图、高度图和相对偏离图进行物体模型的简化)、高度图(high texture)</div>
<div>&nbsp;</div>
<div>七、光照阴影:</div>
<div>光线跟踪(ray trace)、光照图（light map）、阴影图(shadow map)、动态光照(dynamic light)、体积阴影(shadow volumn)、模板阴影(stencil shadow)、顶点光照(vertex light)、像素光照(pixel light)、HDR、PRT</div>
<div>&nbsp;</div>
<div>八、杂项：</div>
<div>粒子动画系统，带子动画系统，3ds max\maya\lightwave\vue infinite插件</div>
<div>&nbsp;</div>
<div>九、图形处理器技术(GPU programming)</div>
<div>vs、ps、HLSL、CG</div>
</div>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113177.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 22:31 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113177.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转载]C++资源之不完全导引（完整版）</title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113175.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 14:30:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113175.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113175.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113175.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113175.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113175.html</trackback:ping><description><![CDATA[<table class="fixedTable blogpost" cellSpacing=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=ellipse><span class=bvTitle id=subjcns!1p5qP-LmQlonNx_ujZCY3OgA!128><strong><font size=3>C++资源之不完全导引（完整版）</font> </strong></span></td>
        </tr>
        <tr>
            <td class=bvh8><strong><font size=3></font></strong></td>
        </tr>
        <tr>
            <td id=msgcns!1p5qP-LmQlonNx_ujZCY3OgA!128>
            <p>C++资源之不完全导引（完整版）</p>
            <p>来源：<a href="http://www.csdn.net/"><u><font color=#0000ff>www.csdn.net</font></u></a></p>
            <p>撰文：曾毅、陶文</p>
            <p>声明：本文2004年5月首发于《CSDN开发高手》，版权归该杂志与《程序员》杂志社<br>所有。</p>
            <p>------------------------------------------------------------------------<br>--------</p>
            </td>
        </tr>
    </tbody>
</table>
<p>　　1，前言</p>
<p>　　无数次听到&#8220;我要开始学习C++!&#8221;的呐喊，无数次听到&#8220;C++太复杂了，我真的<br>学不会&#8221;的无奈。Stan Lippman先生曾在《C++ Primer》一书中指出&#8220;C++是最为难<br>学的高级程序设计语言之一&#8221;，人们常将&#8220;之一&#8221;去掉以表达自己对C++的敬畏。诚<br>然，C++程序设计语言对于学习者的确有很多难以逾越的鸿沟，体系结构的庞大，应<br>接不暇并不断扩充的特性&#8230;&#8230;除此之外，参考资料之多与冗杂使它的学习者望而却<br>步，欲求深入者苦不堪言。希望这一份不完全导引能够成为您C++学习之路上的引路<br>灯。</p>
<p>　　撰写本文的初衷并不打算带领大家体验古老的C++历史，如果你想了解C++的历<br>史与其前期发展中诸多技术的演变，你应当去参考Bjarne的《The Design and Evo<br>lution of C++》。当然也不打算给大家一个无所不包的宝典（并非不想：其一是因<br>水平有限，其二无奈C++之博大精深），所给出的仅仅是一些我们认为对于想学习C<br>++的广大读者来说最重要并且触手可及的开发与学习资源。</p>
<p>　　本文介绍并分析了一些编译器，开发环境，库，少量的书籍以及参考网站，并<br>且尽可能尝试着给出一个利用这些资源的导引，望对如同我们一样的初学者能够有<br>所裨益。</p>
<p>------------------------------------------------------------------------<br>--------</p>
<p>　　2，编译器</p>
<p>　　在C++之外的任何语言中，编译器都从来没有受到过如此之重视。因为C++是一<br>门相当复杂的语言，所以编译器也难于构建。直到最近我们才开始能够使用上完全<br>符合C++标准的编译器（哦，你可能会责怪那些编译器厂商不能尽早的提供符合标准<br>的编译器，这只能怪他们各自维系着自身的一套别人不愿接受的标准）。什么？你<br>说这无关紧要？哦，不，你所需要的是和标准化C++高度兼容的编译环境。长远来看<br>，只有这样的编译器对C++开发人员来说才是最有意义的工具，尤其是对于程序设计<br>语言的学习者。一至性让代码具备可移植性，并让一门语言及其库的应用更为广泛<br>。嗯，是的，我们这里只打算介绍一些公认的优秀编译器。</p>
<p>　　2.1 Borland C++</p>
<p>　　这个是Borland C++ Builder和Borland C++ Builder X这两种开发环境的后台<br>编译器。（哦，我之所以将之分为两种开发环境你应当能明白为什么，正如Delphi<br>7到Delphi8的转变，是革命性的两代。）Borland C++由老牌开发工具厂商Borland<br>倾力打造。该公司的编译器素以速度快，空间效率高著称，Borland C++ 系列编译<br>器秉承了这个传统，属于非常优质的编译器。标准化方面早在5.5版本的编译器中对<br>标准化C++的兼容就达到了92.73%。目前最新版本是Borland C++ Builder X中的6.<br>0版本，官方称100%符合ANSI/ISO的C++标准以及C99标准。嗯&#8230;这正是我前面所指的<br>&#8220;完全符合C++标准的编译器&#8221;。</p>
<p>　　2.2 Visual C++</p>
<p>　　这个正是我们熟知的Visual Studio 和 Visual Studio.net 2002, 2003以及2<br>005 Whidbey中带的C++编译器。由Microsoft公司研制。在Visual Studio 6.0中，<br>因为编译器有太多地方不能与后来出现的C++标准相吻合而饱受批评（想想你在使用<br>STL的时候编译时报出的那些令人厌恶的error和warning吧）。VC++6.0对标准化C+<br>+的兼容只有83.43%。但是随着C++编译器设计大师Stanley Lippman以及诸多C++社<br>群达人的加盟，在Visual Studio.NET 2003中，Visual C++编译器已经成为一个非<br>常成熟可靠的C++编译器了。Dr.Dobb's Journal的评测显示Visual C++7.1对标准C<br>++的兼容性高达98.22%，一度成为CBX之前兼容性最好的编译器。结合强大的Visua<br>l Studio.NET开发环境，是一个非常不错的选择。至于Whidbey时代的Visual C++,<br>似乎微软所最关注的是C++/CLI&#8230;&#8230;我们不想评论微软下一代的C++编译器对标准化<br>兼容如何，但他确实越来越适合.NET (其实你和我的感觉可能是一样的，微软不应<br>当把标准C++这块肥肉丢给Borland,然而微软可能并不这样认为)。</p>
<p>　　2.3 GNU C++</p>
<p>　　著名的开源C++编译器。是类Unix操作系统下编写C++程序的首选。特点是有非<br>常好的移植性，你可以在非常广泛的平台上使用它，同时也是编写跨平台，嵌入式<br>程序很好的选择。另外在符合标准这个方面一直都非常好，GCC3.3大概能够达到96<br>.15%。但是由于其跨平台的特性，在代码尺寸速度等优化上略微差一点。</p>
<p>　　基于GNU C++的编译器有很多，比如：</p>
<p>　　(1) Mingw</p>
<p>　　<a href="http://www.mingw.org/"><u><font color=#0000ff>http://www.mingw.org/</font></u></a></p>
<p>　　GCC的一个Windows的移植版本（Dev-C++的后台）</p>
<p>　　(2) Cygwin</p>
<p>　　<a href="http://sources.redhat.com/cygwin/"><u><font color=#0000ff>http://sources.redhat.com/cygwin/</font></u></a></p>
<p>　　GCC的另外一个Windows移植版本是Cygwin的一部分，Cygwin是Windows下的一个<br>Unix仿真环境。严格的说是模拟GNU的环境，这也就是"Gnu's Not Unix"要表达的意<br>思，噢，扯远了，这并不是我们在这里关心的实质内容。</p>
<p>　　(3) Djgpp</p>
<p>　　<a href="http://www.delorie.com/djgpp/"><u><font color=#0000ff>http://www.delorie.com/djgpp/</font></u></a></p>
<p>　　这是GCC的DOS移植版本。</p>
<p>　　(4) RSXNT</p>
<p>　　<a href="http://www.mathematik.uni-bielefeld.de/~rainer/"><u><font color=#0000ff>http://www.mathematik.uni-bielefeld.de/~rainer/</font></u></a></p>
<p>　　这是GCC的DOS和Windows移植版本。</p>
<p>　　(5) Intel C++</p>
<p>　　著名CPU制造厂商Intel出品的编译器，Special Design for Intel x86！对于<br>Intel x86结构的CPU经过特别的优化。在有些应用情况下，特别是数值计算等高性<br>能应用，仅仅采用Intel的编译器编译就能大幅度的提高性能。</p>
<p>　　(6) Digital Mars C++</p>
<p>　　网络上提供免费下载，Zortech/Symantec C++的继承者，其前身在当年惨烈的<br>C++四国战中也是主角之一。</p>
<p>------------------------------------------------------------------------<br>--------</p>
<p>　　3，开发环境</p>
<p>　　开发环境对于程序员的作用不言而喻。选择自己朝夕相处的环境也不是容易的<br>事情，特别是在IDE如此丰富的情况下。下面就是我们推荐的一些常见的C++开发环<br>境，并没有包括一些小型的，罕见的IDE。其中任何一款都是功能丰富，可以用作日<br>常开发使用的。对于不同层面的开发者，请参见内文关于适用对象的描述。</p>
<p>　　3.1 Visual Studio 6.0</p>
<p>　　这个虽然是Microsoft公司的老版本的开发环境，但是鉴于其后继版本Visual<br>Studio.NET的庞大身躯，以及初学者并不那么高的功能要求，所以推荐这个开发环<br>境给C++的初学者，供其学习C++的最基本的部分，比如C的那部分子集，当然你别指<br>望他能够支持最新的C99标准。在日常的开发中，仍然有很多公司使用这个经典稳定<br>的环境，比如笔者就看曾亲见有些公司将其编译器替换为GCC做手机开发之用。</p>
<p>　　3.2 Visual Studio.NET 2003</p>
<p>　　作为Microsoft公司官方正式发布的最新版本开发环境，其中有太多激动人心的<br>功能。结合其最新的C++编译器。对于机器配置比较好的开发人员来说，使用这个开<br>发环境将能满足其大部分的要求。这里不打算单独说Visual Studio Whidbey,虽然<br>Visual Studio .NET 2005 - Whidbey社区预览版已经推出，但暂不是很稳定，读者<br>可以亲身去体验。</p>
<p>　　3.3 Borland C++ Builder 6</p>
<p>　　这个并不是Borland的C++开发环境的最新版本。选择它的原因是它不是用Java<br>写的IDE，速度比较快。它有一个很完善的GUI窗体设计器，和Delphi共用一个VCL。<br>由于这些特点，比较适合初学者上手。但是由于其GUI的中心位置，可能不利于对于<br>C++语言的学习。而且其为了支持VCL这个Object Pascal写的库也对C++进行了一些<br>私有的扩充。使得人们有一个不得不接受的事实：&#8220;Borland C++ Builder 6的高手<br>几乎都是Delphi高手&#8221;。</p>
<p>　　3.4 Borland C++ Builder X</p>
<p>　　正如前文所述，虽然版本号上和前面那个IDE非常相象，但是其实它们是完全不<br>同的两个集成开发环境。C++Builder更多的是一个和Delphi同步的C++版本的开发环<br>境，C++BuilderX则是完全从C++的角度思考得出的一个功能丰富的IDE。其最大的特<br>点是跨平台，跨编译器，多种Framework的集成，并且有一个WxWindows为基础的GU<br>I设计器。尤其是采用了纯C++来重写了整个Framework,摒弃了以前令人无奈的版本<br>。对于C++的开发来说，从编译器，到库，到功能集成都是非常理想的。可以预见，<br>Borland C++ Builder X 2.0很值得C++爱好者期待。唯一令人难堪之处是作为一个<br>C++的开发工具，其IDE是用Java写的，在配置不够理想的机器上请慎重考虑再安装<br>。</p>
<p>　　3.5 Emacs + GCC</p>
<p>　　前面讲的大部分是Windows环境下的集成开发环境。Linux上的开发者更倾向于<br>使用Emacs来编辑C++的文件，用Makefile来命令GCC做编译。虽然看上去比较松散，<br>但是这些东西综合起来还是一个开0发环境。如果你能够娴熟的使用这样的环境写程<br>序，你的水平应该足够指导我们来写这篇陋文了。</p>
<p>　　3.6 Dev C++</p>
<p>　　GCC是一个很好的编译器。在Windows上的C++编译器一直和标准有着一段距离的<br>时候，GCC就是一个让Windows下开发者流口水的编译器。Dev-C++就是能够让GCC跑<br>在Windows下的工具，作为集成开发环境，还提供了同专业IDE相媲美的语法高亮，<br>代码提示，调试等功能。由于使用Delphi开发，占用内存少，速度很快，比较适合<br>轻量级的学习和使用。</p>
<p>　　3.7 Eclipse + CDT</p>
<p>　　Eclipse可是近来大名鼎鼎的开发工具。最新一期的Jolt大奖就颁给了这个杰出<br>的神物。说其神奇是因为，它本身是用Java写的，但是拥有比一般Java写的程序快<br>得多的速度。而且因为其基于插件组装一切的原则，使得能够有CDT这样的插件把E<br>clipse变成一个C/C++的开发环境。如果你一直用Eclipse写Java的程序，不妨用它<br>体验一下C++开发的乐趣。</p>
<p>------------------------------------------------------------------------<br>--------</p>
<p>　　4，工具</p>
<p>　　C++的辅助工具繁多，我们分门别类的为大家作介绍：</p>
<p>　　4.1 文档类</p>
<p>　　(1) Doxygen</p>
<p>　　参考站点：<a href="http://www.doxygen.org/"><u><font color=#0000ff>http://www.doxygen.org</font></u></a></p>
<p>　　Doxygen是一种适合C风格语言（如C++、C、IDL、Java甚至包括C#和PHP）的、<br>开放源码的、基于命令行的文档产生器。</p>
<p>　　(2) C++2HTML</p>
<p>　　参考站点：<a href="http://www.bedaux.net/cpp2html/"><u><font color=#0000ff>http://www.bedaux.net/cpp2html/</font></u></a></p>
<p>　　把C++代码变成语法高亮的HTML</p>
<p>　　(3) CodeColorizer</p>
<p>　　参考站点：<a href="http://www.chami.com/colorizer/"><u><font color=#0000ff>http://www.chami.com/colorizer/</font></u></a></p>
<p>　　它能把好几种语言的源代码着色为HTML</p>
<p>　　(4) Doc-O-Matic</p>
<p>　　参考站点：<a href="http://www.doc-o-matic.com/"><u><font color=#0000ff>http://www.doc-o-matic.com/</font></u></a></p>
<p>　　Doc-O_Matic为你的C/C++，C++.net，Delphi/Pascal, VB.NET，C#和Java程序<br>或者组件产生准确的文档。Doc-O-Matic使用源代码中的符号和注释以及外部的文档<br>文件创建与流行的文档样式一致的文档。</p>
<p>　　(5) DocVizor</p>
<p>　　参考站点：<a href="http://www.ucancode.net/Products/DocBuilder/Features.htm"><u><font color=#0000ff>http://www.ucancode.net/Products/DocBuilder/Features.htm</font></u></a></p>
<p>　　DocVizor满足了面向对象软件开发者的基本要求——它让我们能够看到C++工程<br>中的类层次结构。DocVizor快速地产生完整可供打印的类层次结构图，包括从第三<br>方库中来的那些类，除此之外DocVizor还能从类信息中产生HTML文件。</p>
<p>　　(6) SourcePublisher C++</p>
<p>　　参考站点：<a href="http://www.scitools.com/sourcepublisher_c.html"><u><font color=#0000ff>http://www.scitools.com/sourcepublisher_c.html</font></u></a></p>
<p>　　给源代码产生提供快速直观的HTML报表，包括代码，类层次结构，调用和被调<br>用树，包含和被包含树。支持多种操作系统。</p>
<p>　　(7) Understand</p>
<p>　　参考站点：<a href="http://www.scitools.com/ucpp.html"><u><font color=#0000ff>http://www.scitools.com/ucpp.html</font></u></a></p>
<p>　　分析任何规模的C或者C++工程，帮助我们更好的理解以及编写文档。</p>
<p>　　4.2 代码类</p>
<p>　　(1) CC-Rider</p>
<p>　　参考站点：<a href="http://www.cc-rider.com/"><u><font color=#0000ff>http://www.cc-rider.com</font></u></a></p>
<p>　　CC-Rider是用于C/C++程序强大的代码可视化工具，通过交互式浏览、编辑及自<br>动文件来促进程序的维持和发展。</p>
<p>　　(2) CodeInspect</p>
<p>　　参考站点：<a href="http://www.yokasoft.com/"><u><font color=#0000ff>http://www.yokasoft.com/</font></u></a></p>
<p>　　一种新的C/C++代码分析工具。它检查我们的源代码找出非标准的，可能的，以<br>及普通的错误代码。</p>
<p>　　(3) CodeWizard</p>
<p>　　参考站点：<a href="http://www.parasoft.com/"><u><font color=#0000ff>http://www.parasoft.com</font></u></a></p>
<p>　　先进的C/C++源代码分析工具，使用超过500个编码规范自动化地标明危险的，<br>但是编译器不能检查到的代码结构。</p>
<p>　　(4) C++ Validation Test Suites</p>
<p>　　参考站点：<a href="http://www.plumhall.com/suites.html"><u><font color=#0000ff>http://www.plumhall.com/suites.html</font></u></a></p>
<p>　　一组用于测试编译器和库对于标准吻合程度的代码库。</p>
<p>　　(5) CppRefactory</p>
<p>　　参考站点：<a href="http://cpptool.sourceforge.net/"><u><font color=#0000ff>http://cpptool.sourceforge.net/</font></u></a></p>
<p>　　CPPRefactory是一个使得开发者能够重构他们的C++代码的程序。目的是使得C<br>++代码的重构能够尽可能的有效率和简单。</p>
<p>　　(6) Lzz</p>
<p>　　参考站点：<a href="http://www.lazycplusplus.com/"><u><font color=#0000ff>http://www.lazycplusplus.com/</font></u></a></p>
<p>　　Lzz是一个自动化许多C++编程中的体力活的工具。它能够节省我们许多事件并<br>且使得编码更加有乐趣。给出一系列的声明，Lzz会给我们创建头文件和源文件。</p>
<p>　　(7) QA C++ Generation 2000</p>
<p>　　参考站点：<a href="http://www.programmingresearch.com/solutions/qacpp.htm"><u><font color=#0000ff>http://www.programmingresearch.com/solutions/qacpp.htm</font></u></a></p>
<p>　　它关注面向对象的C++源代码，对有关于设计，效率，可靠性，可维护性的部分<br>提出警告信息。</p>
<p>　　(8) s-mail project - Java to C++DOL</p>
<p>　　参考站点：<a href="http://sadlocha.strefa.pl/s-mail/ja2dol.html"><u><font color=#0000ff>http://sadlocha.strefa.pl/s-mail/ja2dol.html</font></u></a></p>
<p>　　把Java源代码翻译为相应的C++源代码的命令行工具。</p>
<p>　　(9) SNIP from Cleanscape Software International</p>
<p>　　参考站点：<a href="http://www.cleanscape.net/stdprod/snip/index.html"><u><font color=#0000ff>http://www.cleanscape.net/stdprod/snip/index.html</font></u></a></p>
<p>　　一个填平编码和设计之间沟壑的易于使用的C++开发工具，节省大量编辑和调试<br>的事件，它还使得开发者能够指定设计模式作为对象模型，自动从对象模型中产生<br>C++的类。</p>
<p>　　(10) SourceStyler C++</p>
<p>　　参考站点：<a href="http://www.ochresoftware.com/"><u><font color=#0000ff>http://www.ochresoftware.com/</font></u></a></p>
<p>　　对C/C++源代码提供完整的格式化和排版控制的工具。提供多于75个的格式化选<br>项以及完全支持ANSI C++。</p>
<p>　　4.3 编译类</p>
<p>　　(1) Compilercache</p>
<p>　　参考站点：<a href="http://www.erikyyy.de/compilercache/"><u><font color=#0000ff>http://www.erikyyy.de/compilercache/</font></u></a></p>
<p>　　Compilercache是一个对你的C和C++编译器的封装脚本。每次我们进行编译，封<br>装脚本，把编译的结果放入缓存，一旦编译相同的东西，结果将从缓存中取出而不<br>是再次编译。</p>
<p>　　(2) Ccache</p>
<p>　　参考站点：<a href="http://ccache.samba.org/"><u><font color=#0000ff>http://ccache.samba.org/</font></u></a></p>
<p>　　Ccache是一个编译器缓存。它使用起来就像C/C++编译器的缓存预处理器，编译<br>速度通常能提高普通编译过程的5~10倍。</p>
<p>　　(3) Cmm (C++ with MultiMethods)</p>
<p>　　参考站点：<a href="http://www.op59.net/cmm/cmm-0.28/users.html"><u><font color=#0000ff>http://www.op59.net/cmm/cmm-0.28/users.html</font></u></a></p>
<p>　　这是一种C++语言的扩展。读入Cmm源代码输出C++的源代码，功能是对C++语言<br>添加了对multimethod的支持。</p>
<p>　　(4) The Frost Project</p>
<p>　　参考站点：<a href="http://frost.flewid.de/"><u><font color=#0000ff>http://frost.flewid.de/</font></u></a></p>
<p>　　Forst使得你能够在C++程序中像原生的C++特性一样使用multimethod以及虚函<br>数参数。它是一个编译器的外壳。</p>
<p>　　4.4 测试和调试类</p>
<p>　　(1) CPPUnit</p>
<p>　　CppUnit 是个基于 LGPL 的开源项目，最初版本移植自 JUnit，是一个非常优<br>秀的开源测试框架。CppUnit 和 JUnit 一样主要思想来源于极限编程。主要功能就<br>是对单元测试进行管理，并可进行自动化测试。</p>
<p>　　(2) C++Test</p>
<p>　　参考站点：<a href="http://www.parasoft.com/"><u><font color=#0000ff>http://www.parasoft.com/</font></u></a></p>
<p>　　C++ Test是一个单元测试工具，它自动化了C和C++类，函数或者组件的测试。</p>
<p><br>　　(3) Cantata++</p>
<p>　　参考站点：<a href="http://www.iplbath.com/products/tools/pt400.shtml"><u><font color=#0000ff>http://www.iplbath.com/products/tools/pt400.shtml</font></u></a></p>
<p>　　设计的目的是为了满足在合理的经济开销下使用这个工具可以让开发工程师开<br>展单元测试和集成测试的需求.</p>
<p>　　(4) Purify</p>
<p>　　参考站点：<a href="http://www-900.ibm.com/cn/software/rational/products/purif"><u><font color=#0000ff>http://www-900.ibm.com/cn/software/rational/products/purif</font></u></a><br>yplus/index.shtml</p>
<p>　　IBM Rational PurifyPlus是一套完整的运行时分析工具，旨在提高应用程序的<br>可靠性和性能。PurifyPlus将内存错误和泄漏检测、应用程序性能描述、代码覆盖<br>分析等功能组合在一个单一、完整的工具包中。</p>
<p>　　(5) BoundsChecker</p>
<p>　　BoundsChecker是一个C++运行时错误检测和调试工具。它通过在Visual Studi<br>o内自动化调试过程加速开发并且缩短上市的周期。BoundsChecker提供清楚，详细<br>的程序错误分析，许多是对C++独有的并且在static，stack和heap内存中检测和诊<br>断错误，以及发现内存和资源的泄漏。　　(6) Insure++</p>
<p>　　参考站点：<a href="http://www.parasoft.com/"><u><font color=#0000ff>http://www.parasoft.com/</font></u></a></p>
<p>　　一个自动化的运行时程序测试工具，检查难以察觉的错误,如内存覆盖，内存泄<br>漏，内存分配错误，变量初始化错误，变量定义冲突，指针错误，库错误，逻辑错<br>误和算法错误等。</p>
<p>　　(7) GlowCode</p>
<p>　　参考站点：<a href="http://www.glowcode.com/"><u><font color=#0000ff>http://www.glowcode.com/</font></u></a></p>
<p>　　GlowCode包括内存泄漏检查，code profiler，函数调用跟踪等功能。给C++开<br>发者提供完整的错误诊断，和运行时性能分析工具包。</p>
<p>　　(8) Stack Spy</p>
<p>　　参考站点：<a href="http://www.imperioustech.com/"><u><font color=#0000ff>http://www.imperioustech.com/</font></u></a></p>
<p>　　它能捕捉stack corruption, stack over run, stack overflow等有关栈的错<br>误。</p>
<p>------------------------------------------------------------------------<br>--------</p>
<p>　　5，库</p>
<p>　　在C++中，库的地位是非常高的。C++之父 Bjarne Stroustrup先生多次表示了<br>设计库来扩充功能要好过设计更多的语法的言论。现实中，C++的库门类繁多，解决<br>的问题也是极其广泛，库从轻量级到重量级的都有。不少都是让人眼界大开，亦或<br>是望而生叹的思维杰作。由于库的数量非常庞大，而且限于笔者水平，其中很多并<br>不了解。所以文中所提的一些库都是比较著名的大型库。</p>
<p>　　5.1 标准库</p>
<p>　　标准库中提供了C++程序的基本设施。虽然C++标准库随着C++标准折腾了许多年<br>，直到标准的出台才正式定型，但是在标准库的实现上却很令人欣慰得看到多种实<br>现，并且已被实践证明为有工业级别强度的佳作。</p>
<p>　　(1) Dinkumware C++ Library</p>
<p>　　参考站点：<a href="http://www.dinkumware.com/"><u><font color=#0000ff>http://www.dinkumware.com/</font></u></a></p>
<p>　　P.J. Plauger编写的高品质的标准库。P.J. Plauger博士是Dr. Dobb's程序设<br>计杰出奖的获得者。其编写的库长期被Microsoft采用，并且最近Borland也取得了<br>其OEM的license，在其C/C++的产品中采用Dinkumware的库。</p>
<p>　　(2) RogueWave Standard C++ Library</p>
<p>　　参考站点：<a href="http://www.roguewave.com/"><u><font color=#0000ff>http://www.roguewave.com/</font></u></a></p>
<p>　　这个库在Borland C++ Builder的早期版本中曾经被采用，后来被其他的库给替<br>换了。笔者不推荐使用。</p>
<p>　　(3) SGI STL</p>
<p>　　参考站点：<a href="http://www.roguewave.com/"><u><font color=#0000ff>http://www.roguewave.com/</font></u></a></p>
<p>　　SGI公司的C++标准模版库。</p>
<p>　　(4) STLport</p>
<p>　　参考站点：<a href="http://www.stlport.org/"><u><font color=#0000ff>http://www.stlport.org/</font></u></a></p>
<p>　　SGI STL库的跨平台可移植版本。</p>
<p>　　5.2 &#8220;准&#8221;标准库 - Boost</p>
<p>　　参考站点：<a href="http://www.boost.org/"><u><font color=#0000ff>http://www.boost.org</font></u></a></p>
<p>　　国内镜像：<a href="http://www.c-view.org/tech/lib/boost/index.htm"><u><font color=#0000ff>http://www.c-view.org/tech/lib/boost/index.htm</font></u></a></p>
<p>　　Boost库是一个经过千锤百炼、可移植、提供源代码的C++库，作为标准库的后<br>备，是C++标准化进程的发动机之一。 Boost库由C++标准委员会库工作组成员发起<br>，在C++社区中影响甚大，其成员已近2000人。 Boost库为我们带来了最新、最酷、<br>最实用的技术，是不折不扣的&#8220;准&#8221;标准库。</p>
<p>　　Boost中比较有名气的有这么几个库：</p>
<p>　　Regex</p>
<p>　　正则表达式库</p>
<p>　　Spirit</p>
<p>　　LL parser framework，用C++代码直接表达EBNF</p>
<p>　　Graph</p>
<p>　　图组件和算法</p>
<p>　　Lambda</p>
<p>　　在调用的地方定义短小匿名的函数对象，很实用的functional功能</p>
<p>　　concept check</p>
<p>　　检查泛型编程中的concept</p>
<p>&nbsp;</p>
<p>　　Mpl</p>
<p>　　用模板实现的元编程框架</p>
<p>&nbsp;</p>
<p>　　Thread</p>
<p>　　可移植的C++多线程库</p>
<p>&nbsp;</p>
<p>　　Python</p>
<p>　　把C++类和函数映射到Python之中</p>
<p>　　Pool</p>
<p>　　内存池管理</p>
<p>&nbsp;</p>
<p>　　smart_ptr</p>
<p>　　5个智能指针，学习智能指针必读，一份不错的参考是来自CUJ的文章：</p>
<p>　　Smart Pointers in Boost，哦，这篇文章可以查到，CUJ是提供在线浏览的。<br>中文版见笔者在《Dr. Dobb's Journal软件研发杂志》第7辑上的译文。</p>
<p>　　Boost总体来说是实用价值很高，质量很高的库。并且由于其对跨平台的强调，<br>对标准C++的强调，是编写平台无关，现代C++的开发者必备的工具。但是Boost中也<br>有很多是实验性质的东西，在实际的开发中实用需要谨慎。并且很多Boost中的库功<br>能堪称对语言功能的扩展，其构造用尽精巧的手法，不要贸然的花费时间研读。Bo<br>ost另外一面，比如Graph这样的库则是具有工业强度，结构良好，非常值得研读的<br>精品代码，并且也可以放心的在产品代码中多多利用。</p>
<p>　　5.3 GUI</p>
<p>　　在众多C++的库中，GUI部分的库算是比较繁荣，也比较引人注目的。在实际开<br>发中，GUI库的选择也是非常重要的一件事情，下面我们综述一下可选择的GUI库，<br>各自的特点以及相关工具的支持。</p>
<p>　　(1) MFC</p>
<p>　　大名鼎鼎的微软基础类库（Microsoft Foundation Class）。大凡学过VC++的<br>人都应该知道这个库。虽然从技术角度讲，MFC是不大漂亮的，但是它构建于Windo<br>ws API 之上，能够使程序员的工作更容易,编程效率高，减少了大量在建立 Windo<br>ws 程序时必须编写的代码，同时它还提供了所有一般 C++ 编程的优点，例如继承<br>和封装。MFC 编写的程序在各个版本的Windows操作系统上是可移植的，例如，在<br>Windows 3.1下编写的代码可以很容易地移植到 Windows NT 或 Windows 95 上。但<br>是在最近发展以及官方支持上日渐势微。</p>
<p>　　(2) QT</p>
<p>　　参考网站：<a href="http://www.trolltech.com/"><u><font color=#0000ff>http://www.trolltech.com/</font></u></a></p>
<p>　　Qt是Trolltech公司的一个多平台的C++图形用户界面应用程序框架。它提供给<br>应用程序开发者建立艺术级的图形用户界面所需的所用功能。Qt是完全面向对象的<br>很容易扩展，并且允许真正地组件编程。自从1996年早些时候，Qt进入商业领域，<br>它已经成为全世界范围内数千种成功的应用程序的基础。Qt也是流行的Linux桌面环<br>境KDE 的基础，同时它还支持Windows、Macintosh、Unix/X11等多种平台。</p>
<p>　　(3) WxWindows</p>
<p>　　参考网站：<a href="http://www.wxwindows.org/"><u><font color=#0000ff>http://www.wxwindows.org/</font></u></a></p>
<p>　　跨平台的GUI库。因为其类层次极像MFC，所以有文章介绍从MFC到WxWindows的<br>代码移植以实现跨平台的功能。通过多年的开发也是一个日趋完善的GUI库，支持同<br>样不弱于前面两个库。并且是完全开放源代码的。新近的C++ Builder X的GUI设计<br>器就是基于这个库的。</p>
<p>　　(4) Fox</p>
<p>　　参考网站：<a href="http://www.fox-toolkit.org/"><u><font color=#0000ff>http://www.fox-toolkit.org/</font></u></a></p>
<p>　　开放源代码的GUI库。作者从自己亲身的开发经验中得出了一个理想的GUI库应<br>该是什么样子的感受出发，从而开始了对这个库的开发。有兴趣的可以尝试一下。</p>
<p><br>　　(5) WTL</p>
<p>　　基于ATL的一个库。因为使用了大量ATL的轻量级手法，模板等技术，在代码尺<br>寸，以及速度优化方面做得非常到位。主要面向的使用群体是开发COM轻量级供网络<br>下载的可视化控件的开发者。</p>
<p>　　(6) GTK</p>
<p>　　参考网站：<a href="http://gtkmm.sourceforge.net/"><u><font color=#0000ff>http://gtkmm.sourceforge.net/</font></u></a></p>
<p>　　GTK是一个大名鼎鼎的C的开源GUI库。在Linux世界中有Gnome这样的杀手应用。<br>而GTK就是这个库的C++封装版本。</p>
<p>　　5.4 网络通信</p>
<p>　　(1) ACE</p>
<p>　　参考网站：<a href="http://www.cs.wustl.edu/~schmidt/ACE.html"><u><font color=#0000ff>http://www.cs.wustl.edu/~schmidt/ACE.html</font></u></a></p>
<p>　　C++库的代表，超重量级的网络通信开发框架。ACE自适配通信环境（Adaptive<br>&nbsp;Communication Environment）是可以自由使用、开放源代码的面向对象框架，在<br>其中实现了许多用于并发通信软件的核心模式。ACE提供了一组丰富的可复用C++包<br>装外观（Wrapper Facade）和框架组件，可跨越多种平台完成通用的通信软件任务<br>，其中包括：事件多路分离和事件处理器分派、信号处理、服务初始化、进程间通<br>信、共享内存管理、消息路由、分布式服务动态（重）配置、并发执行和同步，等<br>等。</p>
<p>　　(2) StreamModule</p>
<p>　　参考网站：<a href="http://www.omnifarious.org/StrMod/"><u><font color=#0000ff>http://www.omnifarious.org/StrMod/</font></u></a></p>
<p>　　设计用于简化编写分布式程序的库。尝试着使得编写处理异步行为的程序更容<br>易，而不是用同步的外壳包起异步的本质。</p>
<p>　　(3) SimpleSocket</p>
<p>　　参考网站：<a href="http://home.hetnet.nl/~lcbokkers/simsock.htm"><u><font color=#0000ff>http://home.hetnet.nl/~lcbokkers/simsock.htm</font></u></a></p>
<p>　　这个类库让编写基于socket的客户/服务器程序更加容易。</p>
<p>　　(4) A Stream Socket API for C++</p>
<p>　　参考网站：<a href="http://www.pcs.cnu.edu/~dgame/sockets/socketsC++/sockets.h"><u><font color=#0000ff>http://www.pcs.cnu.edu/~dgame/sockets/socketsC++/sockets.h</font></u></a><br>tml</p>
<p>　　又一个对Socket的封装库。</p>
<p>　　5.5 XML</p>
<p>　　(1) Xerces</p>
<p>　　参考网站：<a href="http://xml.apache.org/xerces-c/"><u><font color=#0000ff>http://xml.apache.org/xerces-c/</font></u></a></p>
<p>　　Xerces-C++ 是一个非常健壮的XML解析器，它提供了验证，以及SAX和DOM API<br>。XML验证在文档类型定义(Document Type Definition，DTD)方面有很好的支持，<br>并且在2001年12月增加了支持W3C XML Schema 的基本完整的开放标准。</p>
<p>　　(2) XMLBooster</p>
<p>　　参考网站：<a href="http://www.xmlbooster.com/"><u><font color=#0000ff>http://www.xmlbooster.com/</font></u></a></p>
<p>　　这个库通过产生特制的parser的办法极大的提高了XML解析的速度，并且能够产<br>生相应的GUI程序来修改这个parser。在DOM和SAX两大主流XML解析办法之外提供了<br>另外一个可行的解决方案。</p>
<p>　　(3) Pull Parser</p>
<p>　　参考网站：<a href="http://www.extreme.indiana.edu/xgws/xsoap/xpp/"><u><font color=#0000ff>http://www.extreme.indiana.edu/xgws/xsoap/xpp/</font></u></a></p>
<p>　　这个库采用pull方法的parser。在每个SAX的parser底层都有一个pull的parse<br>r，这个xpp把这层暴露出来直接给大家使用。在要充分考虑速度的时候值得尝试。</p>
<p><br>　　(4) Xalan</p>
<p>　　参考网站：<a href="http://xml.apache.org/xalan-c/"><u><font color=#0000ff>http://xml.apache.org/xalan-c/</font></u></a></p>
<p>　　Xalan是一个用于把XML文档转换为HTML，纯文本或者其他XML类型文档的XSLT处<br>理器。</p>
<p>　　(5) CMarkup</p>
<p>　　参考网站：<a href="http://www.firstobject.com/xml.htm"><u><font color=#0000ff>http://www.firstobject.com/xml.htm</font></u></a></p>
<p>　　这是一种使用EDOM的XML解析器。在很多思路上面非常灵活实用。值得大家在D<br>OM和SAX之外寻求一点灵感。</p>
<p>　　(6) libxml++</p>
<p>　　<a href="http://libxmlplusplus.sourceforge.net/"><u><font color=#0000ff>http://libxmlplusplus.sourceforge.net/</font></u></a></p>
<p>　　libxml++是对著名的libxml XML解析器的C++封装版本</p>
<p>　　5.6 科学计算</p>
<p>　　(1) Blitz++</p>
<p>　　参考网站：<a href="http://www.oonumerics.org/blitz/"><u><font color=#0000ff>http://www.oonumerics.org/blitz/</font></u></a></p>
<p>　　Blitz++ 是一个高效率的数值计算函数库，它的设计目的是希望建立一套既具<br>像C++ 一样方便，同时又比Fortran速度更快的数值计算环境。通常，用C++所写出<br>的数值程序，比 Fortran慢20%左右，因此Blitz++正是要改掉这个缺点。方法是利<br>用C++的template技术，程序执行甚至可以比Fortran更快。Blitz++目前仍在发展中<br>，对于常见的SVD，FFTs，QMRES等常见的线性代数方法并不提供，不过使用者可以<br>很容易地利用Blitz++所提供的函数来构建。</p>
<p>　　(2) POOMA</p>
<p>　　参考网站：<a href="http://www.codesourcery.com/pooma/pooma"><u><font color=#0000ff>http://www.codesourcery.com/pooma/pooma</font></u></a></p>
<p>　　POOMA是一个免费的高性能的C++库，用于处理并行式科学计算。POOMA的面向对<br>象设计方便了快速的程序开发，对并行机器进行了优化以达到最高的效率，方便在<br>工业和研究环境中使用。</p>
<p>　　(3) MTL</p>
<p>　　参考网站：<a href="http://www.osl.iu.edu/research/mtl/"><u><font color=#0000ff>http://www.osl.iu.edu/research/mtl/</font></u></a></p>
<p>　　Matrix Template Library(MTL)是一个高性能的泛型组件库，提供了各种格式<br>矩阵的大量线性代数方面的功能。在某些应用使用高性能编译器的情况下，比如In<br>tel的编译器，从产生的汇编代码可以看出其与手写几乎没有两样的效能。</p>
<p>　　(4) CGAL</p>
<p>　　参考网站：<a href="http://www.cgal.org/"><u><font color=#0000ff>www.cgal.org</font></u></a></p>
<p>　　Computational Geometry Algorithms Library的目的是把在计算几何方面的大<br>部分重要的解决方案和方法以C++库的形式提供给工业和学术界的用户。</p>
<p>　　5.7 游戏开发</p>
<p>　　(1) Audio/Video 3D C++ Programming Library</p>
<p>　　参考网站：<a href="http://www.galacticasoftware.com/products/av/"><u><font color=#0000ff>http://www.galacticasoftware.com/products/av/</font></u></a></p>
<p>　　***3D是一个跨平台，高性能的C++库。主要的特性是提供3D图形，声效支持（S<br>B,以及S3M），控制接口（键盘，鼠标和遥感），XMS。</p>
<p>　　(2) KlayGE</p>
<p>　　参考网站：<a href="http://home.g365.net/enginedev/"><u><font color=#0000ff>http://home.g365.net/enginedev/</font></u></a></p>
<p>　　国内游戏开发高手自己用C++开发的游戏引擎。KlayGE是一个开放源代码、跨平<br>台的游戏引擎，并使用Python作脚本语言。KlayGE在LGPL协议下发行。感谢龚敏敏<br>先生为中国游戏开发事业所做出的贡献。</p>
<p>　　(3) OGRE</p>
<p>　　参考网站：<a href="http://www.ogre3d.org/"><u><font color=#0000ff>http://www.ogre3d.org</font></u></a></p>
<p>　　OGRE（面向对象的图形渲染引擎）是用C++开发的，使用灵活的面向对象3D引擎<br>。它的目的是让开发者能更方便和直接地开发基于3D硬件设备的应用程序或游戏。<br>引擎中的类库对更底层的系统库（如：Direct3D和OpenGL）的全部使用细节进行了<br>抽象，并提供了基于现实世界对象的接口和其它类。</p>
<p>　　5.8 线程</p>
<p>　　(1) C++ Threads</p>
<p>　　参考网站：<a href="http://threads.sourceforge.net/"><u><font color=#0000ff>http://threads.sourceforge.net/</font></u></a></p>
<p>　　这个库的目标是给程序员提供易于使用的类，这些类被继承以提供在Linux环境<br>中很难看到的大量的线程方面的功能。</p>
<p>　　(2) ZThreads</p>
<p>　　参考网站：<a href="http://zthread.sourceforge.net/"><u><font color=#0000ff>http://zthread.sourceforge.net/</font></u></a></p>
<p>　　一个先进的面向对象，跨平台的C++线程和同步库。</p>
<p>　　5.9 序列化</p>
<p>　　(1) s11n</p>
<p>　　参考网站：<a href="http://s11n.net/"><u><font color=#0000ff>http://s11n.net/</font></u></a></p>
<p>　　一个基于STL的C++库，用于序列化POD，STL容器以及用户定义的类型。</p>
<p>　　(2) Simple XML Persistence Library</p>
<p>　　参考网站：<a href="http://sxp.sourceforge.net/"><u><font color=#0000ff>http://sxp.sourceforge.net/</font></u></a></p>
<p>　　这是一个把对象序列化为XML的轻量级的C++库。</p>
<p>　　5.10 字符串</p>
<p>　　(1) C++ Str Library</p>
<p>　　参考网站：<a href="http://www.utilitycode.com/str/"><u><font color=#0000ff>http://www.utilitycode.com/str/</font></u></a></p>
<p>　　操作字符串和字符的库，支持Windows和支持gcc的多种平台。提供高度优化的<br>代码，并且支持多线程环境和Unicode，同时还有正则表达式的支持。</p>
<p>　　(2) Common Text Transformation Library</p>
<p>　　参考网站：<a href="http://cttl.sourceforge.net/"><u><font color=#0000ff>http://cttl.sourceforge.net/</font></u></a></p>
<p>　　这是一个解析和修改STL字符串的库。CTTL substring类可以用来比较，插入，<br>替换以及用EBNF的语法进行解析。</p>
<p>　　(3) GRETA</p>
<p>　　参考网站：<a href="http://research.microsoft.com/projects/greta/"><u><font color=#0000ff>http://research.microsoft.com/projects/greta/</font></u></a></p>
<p>　　这是由微软研究院的研究人员开发的处理正则表达式的库。在小型匹配的情况<br>下有非常优秀的表现。</p>
<p>　　5.11 综合</p>
<p>　　(1) P::Classes</p>
<p>　　参考网站：<a href="http://pclasses.com/"><u><font color=#0000ff>http://pclasses.com/</font></u></a></p>
<p>　　一个高度可移植的C++应用程序框架。当前关注类型和线程安全的signal/slot<br>机制，i/o系统包括基于插件的网络协议透明的i/o架构，基于插件的应用程序消息<br>日志框架，访问sql数据库的类等等。</p>
<p>　　(2) ACDK - Artefaktur Component Development Kit</p>
<p>　　参考网站：<a href="http://acdk.sourceforge.net/"><u><font color=#0000ff>http://acdk.sourceforge.net/</font></u></a></p>
<p>　　这是一个平台无关的C++组件框架，类似于Java或者.NET中的框架（反射机制，<br>线程，Unicode，废料收集，I/O，网络，实用工具，XML，等等），以及对Java, P<br>erl, Python, TCL, Lisp, COM 和 CORBA的集成。</p>
<p>　　(3) dlib C++ library</p>
<p>　　参考网站：<a href="http://www.cis.ohio-state.edu/~kingd/dlib/"><u><font color=#0000ff>http://www.cis.ohio-state.edu/~kingd/dlib/</font></u></a></p>
<p>　　各种各样的类的一个综合。大整数，Socket，线程，GUI，容器类,以及浏览目<br>录的API等等。</p>
<p>　　(4) Chilkat C++ Libraries</p>
<p>　　参考网站：<a href="http://www.chilkatsoft.com/cpp_libraries.asp"><u><font color=#0000ff>http://www.chilkatsoft.com/cpp_libraries.asp</font></u></a></p>
<p>　　这是提供zip，e-mail，编码，S/MIME，XML等方面的库。</p>
<p>　　(5) C++ Portable Types Library (PTypes)</p>
<p>　　参考网站：<a href="http://www.melikyan.com/ptypes/"><u><font color=#0000ff>http://www.melikyan.com/ptypes/</font></u></a></p>
<p>　　这是STL的比较简单的替代品，以及可移植的多线程和网络库。</p>
<p>　　(6) LFC</p>
<p>　　参考网站：<a href="http://lfc.sourceforge.net/"><u><font color=#0000ff>http://lfc.sourceforge.net/</font></u></a></p>
<p>　　哦，这又是一个尝试提供一切的C++库</p>
<p>　　5.12 其他库</p>
<p>　　(1) Loki</p>
<p>　　参考网站：<a href="http://www.moderncppdesign.com/"><u><font color=#0000ff>http://www.moderncppdesign.com/</font></u></a></p>
<p>　　哦，你可能抱怨我早该和Boost一起介绍它，一个实验性质的库。作者在loki中<br>把C++模板的功能发挥到了极致。并且尝试把类似设计模式这样思想层面的东西通过<br>库来提供。同时还提供了智能指针这样比较实用的功能。</p>
<p>　　(2) ATL</p>
<p>　　ATL(Active Template Library)</p>
<p>　　是一组小巧、高效、灵活的类，这些类为创建可互操作的COM组件提供了基本的<br>设施。</p>
<p>　　(3) FC++: The Functional C++ Library</p>
<p>　　这个库提供了一些函数式语言中才有的要素。属于用库来扩充语言的一个代表<br>作。如果想要在OOP之外寻找另一分的乐趣，可以去看看函数式程序设计的世界。大<br>师Peter Norvig在 &#8220;Teach Yourself Programming in Ten Years&#8221;一文中就将函<br>数式语言列为至少应当学习的6类编程语言之一。</p>
<p>　　(4) FACT!</p>
<p>　　参考网站：<a href="http://www.kfa-juelich.de/zam/FACT/start/index.html"><u><font color=#0000ff>http://www.kfa-juelich.de/zam/FACT/start/index.html</font></u></a></p>
<p>　　另外一个实现函数式语言特性的库</p>
<p>　　(5) Crypto++</p>
<p>　　提供处理密码，消息验证，单向hash，公匙加密系统等功能的免费库。</p>
<p>　　还有很多非常激动人心或者是极其实用的C++库，限于我们的水平以及文章的篇<br>幅不能包括进来。在对于这些已经包含近来的库的介绍中，由于并不是每一个我们<br>都使用过，所以难免有偏颇之处，请读者见谅。</p>
<p>------------------------------------------------------------------------<br>--------</p>
<p>　　6，书籍</p>
<p>　　以前熊节先生曾撰文评论相对于Java程序设计语言，C++的好书多如牛毛。荣耀<br>先生在《程序员》杂志上撰文《C++程序设计之四书五经》也将本领域内几乎所有的<br>经典书籍作了全面的介绍,任何关于书的评论此时看来便是很多余的了。个人浅见，<br>除非你打算以C++作为唯一兴趣或者生存之本，一般读者确实没有足够的时间和必要<br>将20余本书籍全部阅读。更有参考价值的是荣耀先生的另一篇文章：《至少应该阅<br>读的九本C++著作》，可以从下面的地址浏览到此文：</p>
<p>　　<a href="http://www.royaloo.com/articles/articles_2003/9CppBooks.htm"><u><font color=#0000ff>http://www.royaloo.com/articles/articles_2003/9CppBooks.htm</font></u></a></p>
<p>　　下面几本书对于走在C++初学之路上的读者是我们最愿意推荐给大家的：</p>
<p>　　(1) 《C++ Primer》</p>
<p>　　哦，也许你会抱怨我们为什么不先介绍TCPL,但对于走在学习之路上的入门者，<br>本书内容更为全面，更为详细易懂，我们称它为&#8220;C++的超级宝典&#8221;并不过分。配有<br>一本不错的习题解答《C++ Primer Answer Book》可以辅助你的学习之路。</p>
<p>　　(2) 《Essential C++》</p>
<p>　　如果说《C++ Primer》是C++领域的超级宝典，那么此书作为掌握C++的大局观<br>当之无愧。正如《.NET大局观》一书能够让读者全揽.NET，本书讲述了C++中最核心<br>的全部主题。书虽不厚，内容精炼，不失为《C++ Primer》读者茶余饭后的主题回<br>顾之作。</p>
<p>　　(3) 《The C++ Programming Language》</p>
<p>　　Bjarne为你带来的C++教程，真正能够告诉你怎么用才叫真正的C++的唯一一本<br>书。虽然如同&#8220;某某程序设计语言&#8221;这样的书籍会给大家一个内容全揽，入门到精<br>通的感觉，但本书确实不太适合初学者阅读。如果你自认为是一名很有经验的C++程<br>序员，那至少也要反复咀嚼Bjarne先生所强调的若干内容。</p>
<p>　　(4) 《Effective C++》，《More Effective C++》</p>
<p>　　是的，正如一些C++爱好者经常以读过与没有读过上述两本作品来区分你是否是<br>C++高手。我们也极力推崇这两本著作。在各种介绍C++专家经验的书籍里面，这两<br>本是最贴近语言本质，看后最能够有脱胎换骨感觉的书，读此书你需每日三省汝身<br>。</p>
<p>　　技术书籍仁者见仁，过多的评论反无太多意义，由读者喜好选择最适合自己的<br>书方为上策。</p>
<p>------------------------------------------------------------------------<br>--------</p>
<p>　　7，资源网站</p>
<p>　　正如我们可以通过计算机历史上的重要人物了解计算机史的发展，C++相关人物<br>的网站也可以使我们得到最有价值的参考与借鉴，下面的人物我们认为没有介绍的<br>必要，只因下面的人物在C++领域的地位众所周知，我们只将相关的资源进行罗列以<br>供读者学习，他们有的工作于贝尔实验室，有的工作于知名编译器厂商，有的在不<br>断推进语言的标准化，有的为读者撰写了多部千古奇作&#8230;&#8230;<br>　　(1) Bjarne Stroustrup<br>　　<a href="http://www.research.att.com/~bs/"><u><font color=#0000ff>http://www.research.att.com/~bs/</font></u></a></p>
<p>　　(2) Stanley B. Lippman<br>　　<a href="http://blogs.msdn.com/slippman/"><u><font color=#0000ff>http://blogs.msdn.com/slippman/</font></u></a><br>　　中文版 <a href="http://www.zengyihome.net/slippman/index.htm"><u><font color=#0000ff>http://www.zengyihome.net/slippman/index.htm</font></u></a></p>
<p>　　(3) Scott Meyers<br>　　<a href="http://www.aristeia.com/"><u><font color=#0000ff>http://www.aristeia.com/</font></u></a></p>
<p>　　(4) David Musser<br>　　<a href="http://www.cs.rpi.edu/~musser/"><u><font color=#0000ff>http://www.cs.rpi.edu/~musser/</font></u></a></p>
<p>　　(5) Bruce Eckel<br>　　<a href="http://www.bruceeckel.com/"><u><font color=#0000ff>http://www.bruceeckel.com</font></u></a></p>
<p>　　(6) Nicolai M. Josuttis<br>　　<a href="http://www.josuttis.com/"><u><font color=#0000ff>http://www.josuttis.com/</font></u></a></p>
<p>　　(7) Herb Sutter<br>　　<a href="http://www.gotw.ca/"><u><font color=#0000ff>http://www.gotw.ca/</font></u></a></p>
<p>　　(8) Andrei Alexandrescu<br>　　<a href="http://www.coderncppdesign.com/"><u><font color=#0000ff>http://www.coderncppdesign.com/</font></u></a></p>
<p>　　(9) 侯捷先生<br>　　<a href="http://www.jjhou.com/"><u><font color=#0000ff>http://www.jjhou.com</font></u></a></p>
<p>　　(10) 孟岩先生<br>　　先生繁忙于工作，痴迷于技术，暂无个人主页，关于先生的作品可以通过CSDN<br>的专栏和侯先生的主页访问到。</p>
<p>　　(11) 荣耀先生<br>　　<a href="http://www.royaloo.com/"><u><font color=#0000ff>http://www.royaloo.com/</font></u></a></p>
<p>　　(12) 潘爱民先生<br>　　<a href="http://www.icst.pku.edu.cn/panaimin/pam_homepage.htm"><u><font color=#0000ff>http://www.icst.pku.edu.cn/panaimin/pam_homepage.htm</font></u></a></p>
<p>　　除了上述大师的主页外，以下的综合类C++学习参考站点是我们非常愿意向大家<br>推荐的：</p>
<p>　　(1) CodeProject<br>　　<a href="http://www.codeproject.com/"><u><font color=#0000ff>http://www.codeproject.com</font></u></a></p>
<p>　　(2) CodeGuru<br>　　<a href="http://www.codeguru.com/"><u><font color=#0000ff>http://www.codeguru.com</font></u></a></p>
<p>　　(3) Dr. Dobb's Journal<br>　　<a href="http://www.ddj.com/"><u><font color=#0000ff>http://www.ddj.com</font></u></a></p>
<p>　　(4) C/C++ Users Journal<br>　　<a href="http://www.cuj.com/"><u><font color=#0000ff>http://www.cuj.com</font></u></a></p>
<p>　　(5) C维视点<br>　　<a href="http://www.c-view.org/"><u><font color=#0000ff>http://www.c-view.org</font></u></a></p>
<p>　　(6) allaboutprogram<br>　　<a href="http://www.allaboutprogram.com/"><u><font color=#0000ff>http://www.allaboutprogram.com</font></u></a><br>　　其他资料</p>
<p>　　(1) ISO IEC JTC1/SC22/WG21 - C++：标准C++的权威参考<br>　　<a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/"><u><font color=#0000ff>http://anubis.dkuug.dk/jtc1/sc22/wg21/</font></u></a></p>
<p>　　(2) C++ FAQ LITE — Frequently Asked Questions: 最为全面的C++FAQ<br>　　<a href="http://www.sunistudio.com/cppfaq/index.html"><u><font color=#0000ff>http://www.sunistudio.com/cppfaq/index.html</font></u></a><br>　　C/C++ 新闻组：<br>　　你不妨尝试从这里提问和回答问题，很多不错的Q&amp;A资源......</p>
<p>　　(1) .alt.comp.lang.learn.c-c++<br>　　这个简单些，如果你和我一样是个菜鸟</p>
<p>　　(2) .comp.lang.c++.moderated<br>&nbsp;&nbsp;&nbsp; 嗯，这个显然水平高一些</p>
<p>　　(3) .comp.std.c++<br>　　如果你需要讨论标准C++相关话题的话</p>
<p>------------------------------------------------------------------------<br>--------</p>
<p>　　8，不得不写的结束语</p>
<p>　　结束的时候也是总结现状，展望未来的时候。虽然C++从脱胎于C开始，一路艰<br>难坎坷的走过来，但是无论如何C++已经取得了工业基础的地位。文章列举的大量相关<br>资源就是最好的证明，而业界的大量用C++写成的产品代码以及大量的C++职业工程<br>师则是最直接的证明。同时，我们可以看到各个高校的计算机专业都开设有C++这门<br>课程，网络上对于C++的学习讨论也从来都没有停过。但是，在Java和.NET两大企业<br>开发平台的围攻下，给人的感觉是C++越来越&#8220;不行&#8221;了。</p>
<p>　　C++在面向企业的软件开发中，在开发便捷性等方面的确要比Java和C#差很多，<br>其中一个问题是C++语言本身比较复杂，学习曲线比较陡峭，另外一个问题是C++标<br>准化的时间太长，丧失了很多的壮大机会，耗费了很多精力在厂商的之间的斗争上<br>，而C++的标准库离一个完善的程序开发框架还缺少太多太多的内容，各个第三方的<br>类库和框架又在一致性和完整性上没法和随平台提供的框架相提并论。难道C++真的<br>要退出历史舞台了？</p>
<p>　　从C++目前的活跃程度，以及应用现状来说是完全能够肯定C++仍然是软件工业<br>的基础，也不会退出历史舞台的。另外从Boost，Loki这些库中我们也能够看到C++<br>的发展非常活跃，对于新技术新思维非常激进，C++仍然广泛受到关注。从ACE在高<br>性能通信领域的应用，以及MTL这样的库在数值计算领域的出色表现，我们可以看到<br>C++在高性能应用场合下的不可替代的作用，而嵌入式系统这样的内存受限开发平台<br>，比如Symbian OS上，C++已经发挥着并且将发挥更大的作用。可以预见的是以后的<br>软件无论上层的应用怎么变，它的底层核心都会是由C/C++这样的系统级软件编写的<br>，比如Java虚拟机，.NET Framwork。因为只有这样的系统级软件才能完全彻底的发<br>挥机器的功能。</p>
<p>　　需要看到的是两个趋势，一个趋势是C++变得更加复杂，更加学院派，通过模板<br>等有潜力的语法因素构造越来越精巧的库成为了现代C++的热点，虽然在利用库实现<br>新的编程范式，乃至设计模式等方面很有开创意义，也确实产生了一些能够便捷开<br>发的工具，但是更多的是把C++变得更加强大，更加复杂，也更加难懂，似乎也更加<br>学院派，不得不说它正在向边缘化道路发展。另一个趋势是C++在主流的企业应用开<br>发中已经逐渐退出了，ERP这样的企业软件开发中基本上不会考虑C++，除非需要考<br>虑性能或者和遗留代码的集成这些因素。C++退守到系统级别语言，成为软件工业的<br>基础是大势所趋。然而反思一下，真的是退守么？自从STL出现，无数的人风起云涌<br>的开始支持C++,他们狂呼&#8220;我看到深夜消失了，目标软件工程的出现。我看到了可<br>维护的代码。&#8221;是的，STL在可维护性下做得如此出色。但是又怎样呢？STL为C++铺<br>平了现代软件工程的道路，而在上层应用程序软件开发领域这块场地早不单独属于<br>C++,很多程序设计语言都做得很出色，疯狂的支持者会毫不犹豫地说我们应当支持<br>C++,因为它是世界上最棒的语言。而坦率地说，你的腰杆真的那么硬么？也许只是<br>在逃避一些事实。C++是优秀的，这不可否认，STL的出现让C++一度走上了最辉煌的<br>时刻，然而现在看来&#8230;&#8230;我的一位恩师曾言：真正能够将STL应用得淋漓尽致的人很<br>保守地说国内也不超过200人，或许不加入STL能够使C++向着它应当发展的方向发展<br>的更好，而现在看来，C++也应当回首到真正属于他的那一片圣地上&#8230;&#8230;</p>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113175.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 22:30 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113175.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转载]转自OGRE的一些游戏编程的链接 </title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113174.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 14:27:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113174.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113174.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113174.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113174.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113174.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: C++ / STL[edit]Introduction / Help    C++ slides Optimisations, Templates and good use of heritage and polymorphisms (http://www.rz.rwth-aachen.de/computing/events/2002/hpc++/HPC++1.18-1.pdf...&nbsp;&nbsp;<a href='http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113174.html'>阅读全文</a><img src ="http://www.cppblog.com/iwangchuchu/aggbug/113174.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 22:27 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113174.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[原创]LuaPlus上手指南(1) </title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113173.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 14:05:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113173.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113173.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113173.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113173.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113173.html</trackback:ping><description><![CDATA[<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 15pt; FONT-FAMILY: 宋体; mso-no-proof: yes">LuaPlus</span></strong><strong style="mso-bidi-font-weight: normal"><span style="FONT-SIZE: 15pt; FONT-FAMILY: 宋体; mso-no-proof: yes">上手指南<span lang=EN-US>(1)<o:p></o:p></span></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-FAMILY: 宋体; mso-no-proof: yes; mso-bidi-font-size: 10.5pt"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-FAMILY: 宋体; mso-no-proof: yes; mso-bidi-font-size: 10.5pt"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-no-proof: yes">版权所有<span lang=EN-US>,</span>转载请注明出处<span lang=EN-US>,</span>勿用于商业用途<span lang=EN-US>,</span>谢谢<span lang=EN-US>!<o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-no-proof: yes">作者<span lang=EN-US>:<span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span></span>大宝天天见<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-no-proof: yes">Blog:<span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span><a href="http://www.cppblog.com/singohgod"><u><font color=#800080>http://www.cppblog.com/singohgod</font></u></a><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-no-proof: yes">本人水平有限<span lang=EN-US>,</span>有错请指出<span lang=EN-US>,</span>欢迎交流<span lang=EN-US>,</span>共同进步<span lang=EN-US>!<br><br><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-FAMILY: 宋体; mso-no-proof: yes; mso-bidi-font-size: 10.5pt"><o:p><img height=120 src="http://www.cppblog.com/images/cppblog_com/singohgod/4054/t_Lua_LOGO.jpg" width=119 border=0>&nbsp;<img height=120 src="http://www.cppblog.com/images/cppblog_com/singohgod/4054/t_LuaPlus_LOGO.jpg" width=120 border=0><br></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">国内关于</span><span lang=EN-US>Lua</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的资料实在是太少</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为了寻找一个合适的</span><span lang=EN-US>Lua</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang=EN-US>C++</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">封装</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">真是如同大海捞针</span><span lang=EN-US>.</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在看了众多资料后锁定以下几种</span><span lang=EN-US>:LuaBind ToLua++ LuaPlus.</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在选择上颇有讽刺的味道</span><span lang=EN-US>,LuaBind</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的版本号还没到</span><span lang=EN-US>1.0,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">加上网友颇有微词</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">放弃</span><span lang=EN-US>.ToLua++</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">本来有朋友推荐</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">但是怎么都找不到下载</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">官网就是打不开</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">无赖放弃</span><span lang=EN-US>.</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就只有</span><span lang=EN-US>LuaPlus</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">了</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">看到一些人的评价还行</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">于是决定就用它吧</span><span lang=EN-US>.</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><span lang=EN-US>LuaPlus</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的资料就更少了</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">连怎么配置怎么调试等什么都没有</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">只有沐枫大哥讲解了语法方面的一篇文章</span><span lang=EN-US>.</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">啊哟</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">怎么搞呢</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">难道又只有硬着头皮上了</span><span lang=EN-US>?(</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">某伟人曾说过</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">但凡杰出的事都是硬着头皮干出来滴</span><span lang=EN-US>)</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">好了</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">言归正传</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下面讲讲我的经验吧</span><span lang=EN-US>:</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span style="FONT-SIZE: 14pt; COLOR: red; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如何编译</span></strong><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 14pt; COLOR: red"><o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="COLOR: maroon; mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">1.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span></strong><strong style="mso-bidi-font-weight: normal"><span style="COLOR: maroon; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下载</span><span lang=EN-US style="COLOR: maroon"><o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">首先到官方网站下载</span><span lang=EN-US>: <a href="http://www.luaplus.org/"><u><font color=#0000ff>http://www.luaplus.org/</font></u></a></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下载这个</span><span lang=EN-US>: All source code: <a href="http://luaplus.org/LuaPlus51_Build1100.zip"><u><font color=#0000ff>http://luaplus.org/LuaPlus51_Build1100.zip</font></u></a> (</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我当前的版本</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当然越新越好</span><span lang=EN-US>)</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="COLOR: maroon; mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">2.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span></strong><strong style="mso-bidi-font-weight: normal"><span style="COLOR: maroon; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">剥离</span><span lang=EN-US style="COLOR: maroon"><o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">解开下载包</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打开</span> <span lang=EN-US>\LuaPlus51_Build1100\Src\LuaPlus </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">里面是全部源文件</span><span lang=EN-US>,src</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下是</span><span lang=EN-US>lua</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的源文件</span><span lang=EN-US>.</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这里有个令人疑惑的地方</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">源文件中带了一些不需要的文件</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">要剔除去</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">基本上需要以下这些文件</span><span lang=EN-US>:</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level2 lfo1; tab-stops: list 39.0pt"><span lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">1)<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span lang=EN-US>Lua</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">库文件</span><span lang=EN-US>:</span></p>
<p>
<table class=MsoTableGrid style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes">
            <td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 142pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt" vAlign=top width=189>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lapi.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lapi.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lauxlib.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lauxlib.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lbaselib.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lcode.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lcode.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>ldblib.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>ldebug.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>ldebug.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>ldo.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>ldo.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>ldump.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lfunc.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lfunc.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lgc.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lgc.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>linit.c</span></p>
            </td>
            <td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" vAlign=top width=189>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>liolib.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>llex.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>llex.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>llimits.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lmathlib.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lmem.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lmem.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>loadlib.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lobject.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lobject.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lopcodes.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lopcodes.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>loslib.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lparser.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lparser.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lstate.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lstate.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lstring.c</span></p>
            </td>
            <td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" vAlign=top width=189>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lstring.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lstrlib.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>ltable.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>ltable.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>ltablib.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>ltm.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>ltm.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lua.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>luaconf.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lualib.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lundump.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lundump.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lvm.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lvm.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lzio.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lzio.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>print.c</span></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level2 lfo1; tab-stops: list 39.0pt"><span lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">2)<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span lang=EN-US>LuaPlus</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">头文件</span><span lang=EN-US>:</span></p>
<p>
<table class=MsoTableGrid style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes">
            <td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 213.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt" vAlign=top width=284>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>auxiliar.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaAutoBlock.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaCall.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaFunction.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaHelper.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaHelper_Object.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaHelper_StackObject.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaLink.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaObject.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaObject.inl</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaPlus.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaPlusCD.h</span></p>
            </td>
            <td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 213.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" vAlign=top width=284>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaPlusFunctions.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaPlusInternal.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaStackObject.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaStackObject.inl</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaStackTableIterator.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaState.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaState.inl</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaStateOutFile.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaTableIterator.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>luathread.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>pt.h</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>srm.h</span></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt; mso-list: l0 level2 lfo1; tab-stops: list 39.0pt"><span lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">3)<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span lang=EN-US>LuaPlus</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">源文件</span></p>
<p>
<table class=MsoTableGrid style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes">
            <td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 213.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt" vAlign=top width=284>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaCall.cpp</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaObject.cpp</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaPlus.cpp</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaPlusAddons.c</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaPlusFunctions.cpp</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaPlus_Libs.cpp</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaStackObject.cpp</span></p>
            </td>
            <td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #ece9d8; WIDTH: 213.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" vAlign=top width=284>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaStackTableIterator.cpp</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaState.cpp</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaStateOutFile.cpp</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaState_DumpObject.cpp</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>LuaTableIterator.cpp</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US>lwstrlib.c</span></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="COLOR: maroon; mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">3.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span></strong><strong style="mso-bidi-font-weight: normal"><span style="COLOR: maroon; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">建立项目</span><span lang=EN-US style="COLOR: maroon"><o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">然后你就可以在</span><span lang=EN-US>VS</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中建立一个新项目</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">静态链接库的</span><span lang=EN-US>:</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><v:shapetype id=_x0000_t75 coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></v:path><o:lock v:ext="edit" aspectratio="t"><img src="http://www.cppblog.com/images/cppblog_com/singohgod/4054/o_1.jpg" border=0></o:lock></v:shapetype></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">分别把需要的文件加进去</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">之后编译</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应该能通过了</span><span lang=EN-US>.</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span style="FONT-SIZE: 14pt; COLOR: red; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如何使用</span></strong><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 14pt; COLOR: red"><o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接着讲讲如何在你的其他项目中使用</span><span lang=EN-US>LuaPlus.</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="COLOR: maroon">1.</span></strong><strong style="mso-bidi-font-weight: normal"><span style="COLOR: maroon; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">必要的配置</span><span lang=EN-US style="COLOR: maroon"><o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">你的项目可能是这样的</span><span lang=EN-US>:</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><img src="http://www.cppblog.com/images/cppblog_com/singohgod/4054/o_2.jpg" border=0></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设置</span><span lang=EN-US>GameClient</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的依赖项是</span><span lang=EN-US>LuaPlusLib</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue">#include "LuaPlus.h"<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue">using namespace LuaPlus;<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">记得干这事</span><span lang=EN-US>&#8230;</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="COLOR: maroon">2.</span></strong><strong style="mso-bidi-font-weight: normal"><span style="COLOR: maroon; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">创建一个状态</span><span lang=EN-US style="COLOR: maroon"><o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue">LuaStateOwner state;<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">今后的操作都围绕这个</span><span lang=EN-US>state</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; mso-para-margin-left: 2.0gd"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="COLOR: maroon">3.</span></strong><strong style="mso-bidi-font-weight: normal"><span style="COLOR: maroon; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">执行脚本</span><span lang=EN-US style="COLOR: maroon"><o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue">int iret = state-&gt;DoFile("test.lua");<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">返回值为</span><span lang=EN-US>0</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示成功</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">否则不成功</span><span lang=EN-US>.</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; mso-para-margin-left: 2.0gd"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="COLOR: maroon">4.C++</span></strong><strong style="mso-bidi-font-weight: normal"><span style="COLOR: maroon; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中获取</span><span lang=EN-US style="COLOR: maroon">Lua</span></strong><strong style="mso-bidi-font-weight: normal"><span style="COLOR: maroon; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">脚本的变量</span><span lang=EN-US style="COLOR: maroon"><o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">假设你的</span><span lang=EN-US>test.lua</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中有</span><span lang=EN-US>: </span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>health = 200;</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通过下列方法就可以在</span><span lang=EN-US>C++</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中得到这个数值</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue">int mytest = state-&gt;GetGlobal("health").GetInteger();<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; mso-para-margin-left: 2.0gd"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="COLOR: maroon">5.C++</span></strong><strong style="mso-bidi-font-weight: normal"><span style="COLOR: maroon; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中调用</span><span lang=EN-US style="COLOR: maroon">Lua</span></strong><strong style="mso-bidi-font-weight: normal"><span style="COLOR: maroon; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">脚本里的函数</span><span lang=EN-US style="COLOR: maroon"><o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">假设你的</span><span lang=EN-US>test.lua</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中有</span><span lang=EN-US>:</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue">function Add(x, y) <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return x+y; <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue">end<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span><span lang=EN-US>C++</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中需要先声明这个函数</span><span lang=EN-US>:</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue">LuaFunction&lt;float&gt; Add =<span style="mso-spacerun: yes">&nbsp; </span>state-&gt;GetGlobal("Add");<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这样你就有了</span><span lang=EN-US>Add()</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">然后就可以像平常一样使用它了</span><span lang=EN-US>:</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue">float myret = Add(<st1:chmetcnv UnitName="F" SourceValue="3.14" HasSpace="False" Negative="False" NumberType="1" TCSC="0" w:st="on">3.14f</st1:chmetcnv>,<st1:chmetcnv UnitName="F" SourceValue="5.25" HasSpace="False" Negative="False" NumberType="1" TCSC="0" w:st="on">5.25f</st1:chmetcnv>);<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; mso-para-margin-left: 2.0gd"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="COLOR: maroon">6.Lua</span></strong><strong style="mso-bidi-font-weight: normal"><span style="COLOR: maroon; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">脚本中调用</span><span lang=EN-US style="COLOR: maroon">C++</span></strong><strong style="mso-bidi-font-weight: normal"><span style="COLOR: maroon; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数</span><span lang=EN-US style="COLOR: maroon"><o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在读取</span><span lang=EN-US>test.lua</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">之前要先把</span><span lang=EN-US>C++</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数注册到</span><span lang=EN-US>Lua</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的运行时栈里</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这样在执行</span><span lang=EN-US>lua</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">脚本的时候</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">才知道执行哪一个函数</span><span lang=EN-US>:</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">首先有函数</span><span lang=EN-US>:</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue">int LS_PrintNumber(LuaState* state)<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue">{<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; mso-para-margin-left: 2.0gd"><span lang=EN-US style="COLOR: blue">LuaStack args(state);<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if (args[1].IsNumber()) {<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue"><span style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>printf("%f\n", args[1].GetNumber());<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return 0;<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue">}<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">然后注册这个函数到</span><span lang=EN-US>Lua:</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue">state-&gt;GetGlobals().Register("PrintNumber", LS_PrintNumber);<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这样就把</span><span lang=EN-US>LS_PrintNumber</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">映射为</span><span lang=EN-US>Lua</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中可以使用的函数</span><span lang=EN-US>PrintNumber.</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>Test.lua</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">脚本中添加调用语句</span><span lang=EN-US>:</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="COLOR: blue">PrintNumber(30);<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当</span><span lang=EN-US style="COLOR: blue">state-&gt;DoFile("test.lua");</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">执行的时候</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就执行了</span><span lang=EN-US>C++</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的这个函数</span><span lang=EN-US>.</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span style="FONT-SIZE: 14pt; COLOR: red; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">总结</span></strong><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 14pt; COLOR: red"><o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">本文介绍了</span><span lang=EN-US>LuaPlus</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的基本配置方法和使用</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">希望对你有帮助</span><span lang=EN-US>.</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下一篇将介绍一些高级特性</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如怎样在</span><span lang=EN-US>VS</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中调试</span><span lang=EN-US>LuaPlus</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的脚本</span><span lang=EN-US>,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以及对类的操作等</span><span lang=EN-US>.<br></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt">如果还有任何疑问可以看看下面这个简单的例子:<span lang=EN-US><o:p><br>&nbsp;<a href="http://www.cppblog.com/Files/singohgod/LuaPlus_Test.rar"><font color=#1a8bc8>/Files/singohgod/LuaPlus_Test.rar</font></a></o:p></span></p>
<p>&nbsp;</p>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113173.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 22:05 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113173.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转贴】Lua常用资源连接(来自lua-users) </title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113168.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 13:48:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113168.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113168.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113168.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113168.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113168.html</trackback:ping><description><![CDATA[<ul>
    <li>官方资源&nbsp;
    <ul>
        <li><a href="http://www.lua.org/"><u><font face=Verdana color=#800080 size=2>[Lua 官方主页]</font></u></a></li>
    </ul>
    <li>Lua社区&nbsp;
    <ul>
        <li><a href="http://lua-users.org/lists/lua-l/"><u><font face=Verdana color=#0000ff size=2>[Lua 邮件列表]</font></u></a>
        <li><a href="irc://irc.freenode.net/lua"><u><font face=Verdana color=#800080 size=2>[Lua IRC 聊天频道]</font></u></a> (#来自irc.freenode.net)
        <li><a href="http://mini.net/cgi-bin/lua/"><u><font face=Verdana color=#0000ff size=2>[Jean-Claude Wippler的wiki]</font></u></a>. <em>(不再维护)</em></li>
    </ul>
    <li>Lua&nbsp;文档
    <ul>
        <li><em><a href="http://www.tecgraf.org/~mark/luaarchitecture.doc"><u><font face=Verdana color=#0000ff size=2>[Lua架构]</font></u></a></em> - 描述了Lua的业务驱动方式，目的以及架构解决方案。</li>
    </ul>
    <li>带有例证的Lua文档
    <ul>
        <li><em><a href="http://www.acmqueue.org/modules.php?name=Content&amp;pa=showpage&amp;pid=112"><u><font face=Verdana color=#0000ff size=2>[与Will Harvey的谈话记录]</font></u></a></em></li>
    </ul>
    <li>Lua&nbsp;教程
    <ul>
        <li><a href="http://www.gamedev.net/reference/articles/article1932.asp"><u><font face=Verdana color=#0000ff size=2>[来自GameDev.net的：An Introduction to Lua]</font></u></a>
        <li><a href="http://davespalace.co.uk/tutorials/lua_extend.html"><u><font face=Verdana color=#0000ff size=2>[扩展性的Lua]</font></u></a>
        <li><a href="http://davespalace.co.uk/tutorials/lua_embed.html"><u><font face=Verdana color=#0000ff size=2>[嵌入式的 Lua]</font></u></a>
        <li><a href="http://smorgasbordet.com/phpBB2/viewtopic.php?p=778#778"><u><font face=Verdana color=#0000ff size=2>[Win32平台下使用Pelles C编译Lua]</font></u></a>
        <li><a href="http://www.blitzwiki.org/index.php/Introduction_to_Lua"><u><font face=Verdana color=#0000ff size=2>[在BlitzMax中使用 Lua]</font></u></a></li>
    </ul>
    <li>认证考试&nbsp;
    <ul>
        <li><a href="http://www.high-levelcert.com/"><u><font face=Verdana color=#0000ff size=2>[Lua高级认证]</font></u></a> 提供Lua认证考试和相关练习. </li>
    </ul>
    <li>Benchmarks
    <ul>
        <li><a href="http://cm.bell-labs.com/cm/cs/who/bwk/interps/pap.html"><u><font face=Verdana color=#0000ff size=2>[Experiments with Scripting and User-Interface Language]</font></u></a> is a paper by Kernighan and Van Wyk that benchmarks several scripting languages. An <a href="http://www.inf.puc-rio.br/~roberto/bwk-lua.tar.gz"><u><font face=Verdana color=#0000ff size=2>[implementation]</font></u></a> of these benchmarks in Lua is available.
        <li>Doug Bagley's的书： <a href="http://shootout.alioth.debian.org/"><u><font face=Verdana color=#0000ff size=2>[Great Computer Language Shootout]</font></u></a> 的更新版本.还有一个不太新的<a href="http://dada.perl.it/shootout/"><u><font face=Verdana color=#0000ff size=2>[Windows版本]</font></u></a> . </li>
    </ul>
    <li>语言比较&nbsp;
    <ul>
        <li><a href="http://www.latech.edu/~acm/HelloWorld.shtml"><u><font face=Verdana color=#0000ff size=2>[Hello World!]</font></u></a>
        <li><a href="http://kevin.alteu.com/code/helloyou/index.html"><u><font face=Verdana color=#0000ff size=2>[Hello You]</font></u></a>: <a href="http://kevin.alteu.com/code/helloyou/lua.html"><u><font face=Verdana color=#0000ff size=2>[Lua entry]</font></u></a>.
        <li><a href="http://www.99-bottles-of-beer.net/"><u><font face=Verdana color=#0000ff size=2>[99 Bottles of Beer]</font></u></a>: <a href="http://www.99-bottles-of-beer.net/language-lua-365.html"><u><font face=Verdana color=#0000ff size=2>[Lua entry]</font></u></a>.
        <li><a href="http://www.miranda.org/~jkominek/rot13/"><u><font face=Verdana color=#0000ff size=2>[ROT13]</font></u></a>: <a href="http://www.miranda.org/~jkominek/rot13/lua/"><u><font face=Verdana color=#0000ff size=2>[Lua entry]</font></u></a>
        <li><a href="http://www.nyx.net/~gthompso/quine.htm"><u><font face=Verdana color=#0000ff size=2>[The Quine Page]</font></u></a>
        <li><a href="http://www.angelfire.com/tx4/cus/shapes/index.html"><u><font face=Verdana color=#0000ff size=2>[OO 例子]</font></u></a>
        <li><a href="http://www.kochandreas.com/home/language/lang.htm"><u><font face=Verdana color=#0000ff size=2>[APLC: Andreas' 实践语言对比]</font></u></a>.
        <li><a href="http://***.sourceforge.net/pixel/language-study/scripting-language/"><u><font face=Verdana color=#0000ff size=2>[Scriptometer]</font></u></a>
        <li><a href="http://***.sourceforge.net/pixel/language-study/syntax-across-languages.html"><u><font face=Verdana color=#0000ff size=2>[Syntax accross languages]</font></u></a> (Big page!)
        <li><a href="http://www.ntecs.de/old-hp/uu9r/lang/html/lang.en.html"><u><font face=Verdana color=#0000ff size=2>[Michael Neumann's关于语言的比较]</font></u></a>
        <li><a href="http://csl.sublevel3.org/lua/"><u><font face=Verdana color=#0000ff size=2>[与C++一起使用Lua:简短的教程]</font></u></a>
        <li><a href="http://pleac.sourceforge.net/"><u><font face=Verdana color=#0000ff size=2>[PLEAC - 类似食谱一样的编程语言例子]</font></u></a></li>
    </ul>
    <li>Lua 其他相关站点
    <ul>
        <li><a href="http://groups.google.com/groups?as_q=Lua&amp;num=20&amp;as_scoring=date&amp;btnG=Google+Search&amp;as_ugroup=comp.*+*game*&amp;as_drrb=quick"><u><font face=Verdana color=#0000ff size=2>[Lua使用指南]</font></u></a>,&nbsp;来自 <a href="http://groups.google.com/"><u><font face=Verdana color=#0000ff size=2>[Google Groups]</font></u></a>.
        <li><a href="http://www.ddj.com/topics/altlang/sites.htm?topic=altlang"><u><font face=Verdana color=#0000ff size=2>[Dr. Dobb's 的脚本语言列表]</font></u></a>.
        <li><a href="http://www.idiom.com/free-compilers/"><u><font face=Verdana color=#0000ff size=2>[免费的编译器和解释器分类]</font></u></a>: <a href="http://www.idiom.com/free-compilers/TOOL/lua-1.html"><u><font face=Verdana color=#0000ff size=2>[Lua entry]</font></u></a>.
        <li><a href="http://www.erols.com/ziring/dopl.html"><u><font face=Verdana color=#0000ff size=2>[编程语言字典]</font></u></a>: <a href="http://cgibin.erols.com/ziring/cgi-bin/cep/cep.pl?_key=Lua"><u><font face=Verdana color=#0000ff size=2>[Lua entry]</font></u></a>.
        <li><a href="http://sal.kachinatech.com/"><u><font face=Verdana color=#0000ff size=2>[SAL, Linux上的科学上的应用]</font></u></a>: <a href="http://sal.kachinatech.com/F/1/LUA.html"><u><font face=Verdana color=#0000ff size=2>[Lua entry]</font></u></a> (site no longer exists?).
        <li><a href="http://freshmeat.net/"><u><font face=Verdana color=#0000ff size=2>[Freshmeat]</font></u></a>: <a href="http://freshmeat.net/projects/lua/"><u><font face=Verdana color=#0000ff size=2>[Lua entry]</font></u></a>.
        <li><a href="http://www.freebsd.org/"><u><font face=Verdana color=#0000ff size=2>[FreeBSD]</font></u></a>: <a href="http://www.freebsd.org/ports/lang.html"><u><font face=Verdana color=#0000ff size=2>[Lua entry]</font></u></a>.
        <li><a href="http://www.netbsd.org/"><u><font face=Verdana color=#0000ff size=2>[NetBSD]</font></u></a>: <a href="ftp://ftp.netbsd.org/pub/NetBSD/packages/pkgsrc/lang/lua/README.html"><u><font face=Verdana color=#0000ff size=2>[Lua entry]</font></u></a>.
        <li><a href="http://www.mathtools.net/"><u><font face=Verdana color=#0000ff size=2>[Mathtools.net]</font></u></a>: <a href="http://www.mathtools.net/C++/Interpreters/Other/"><u><font face=Verdana color=#0000ff size=2>[Lua entry]</font></u></a> (404 error).
        <li><a href="http://www.wikipedia.com/"><u><font face=Verdana color=#0000ff size=2>[Wikipedia]</font></u></a>: <a href="http://wikipedia.org/wiki/Lua_programming_language"><u><font face=Verdana color=#0000ff size=2>[Lua entry]</font></u></a>.
        <li><a href="http://www.conectiva.com/"><u><font face=Verdana color=#0000ff size=2>[Conectiva]</font></u></a>: <a href="http://snapshot.conectiva.com/SRPMS/Interpreters/lua.html"><u><font face=Verdana color=#0000ff size=2>[Lua entry]</font></u></a> (404 error).
        <li><a href="http://www.hypernews.org/HyperNews/get/computing/lang-list.html"><u><font face=Verdana color=#0000ff size=2>[Hypernews Computer Language List]</font></u></a>.
        <li><a href="http://wuarchive.wustl.edu/doc/misc/lang-list.txt"><u><font face=Verdana color=#0000ff size=2>[语言列表- Version 2.4]</font></u></a> (开始于1995年! 现在404错误,&nbsp;到 <a href="http://wuarchive.wustl.edu/"><u><font face=Verdana color=#0000ff size=2>[主页]</font></u></a> 察看原因).
        <li><a href="http://cliki.tunes.org/Programming%20Languages"><u><font face=Verdana color=#0000ff size=2>[现存语言的评论]</font></u></a>: <a href="http://cliki.tunes.org/LUA"><u><font face=Verdana color=#0000ff size=2>[Lua entry]</font></u></a>.
        <li><a href="http://dmoz.org/"><u><font face=Verdana color=#0000ff size=2>[开源的工程目录]</font></u></a>: <a href="http://dmoz.org/Computers/Programming/Languages/Lua/"><u><font face=Verdana color=#0000ff size=2>[Lua entry]</font></u></a>.
        <li><a href="http://www.gnu.org/directory/"><u><font face=Verdana color=#0000ff size=2>[GNU 自由软件目录]</font></u></a>: <a href="http://www.gnu.org/directory/lua.html"><u><font face=Verdana color=#0000ff size=2>[Lua entry]</font></u></a>.
        <li><a href="http://www.scriptol.org/choose.php"><u><font face=Verdana color=#0000ff size=2>[流行的脚本语言]</font></u></a></li>
    </ul>
    </li>
</ul>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113168.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 21:48 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/21/113168.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转载]低耦合模块间的通信组件：两个模板</title><link>http://www.cppblog.com/iwangchuchu/archive/2010/04/20/113100.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Tue, 20 Apr 2010 14:21:00 GMT</pubDate><guid>http://www.cppblog.com/iwangchuchu/archive/2010/04/20/113100.html</guid><wfw:comment>http://www.cppblog.com/iwangchuchu/comments/113100.html</wfw:comment><comments>http://www.cppblog.com/iwangchuchu/archive/2010/04/20/113100.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/iwangchuchu/comments/commentRss/113100.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iwangchuchu/services/trackbacks/113100.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 10pt"><strong>用途</strong></p>
<p style="FONT-SIZE: 10pt">在一个UI与逻辑模块交互比较多的程序中，因为并不想让两个模块发生太大的耦合，基本目标是<br>可以完全不改代码地换一个UI。逻辑模块需要在产生一些事件后通知到UI模块，并且在这个通知<br>里携带足够多的信息（数据）给接收通知的模块，例如UI模块。逻辑模块还可能被放置于与UI模<br>块不同的线程里。</p>
<p style="FONT-SIZE: 10pt"><strong>最初的结构</strong></p>
<p style="FONT-SIZE: 10pt">最开始我直接采用最简单的方法，逻辑模块保存一个UI模块传过来的listener。当有事件发生时，<br>就回调相应的接口将此通知传出去。大致结构如下：<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id=Codehighlighter1_1_10_Open_Image onclick="this.style.display='none'; Codehighlighter1_1_10_Open_Text.style.display='none'; Codehighlighter1_1_10_Closed_Image.style.display='inline'; Codehighlighter1_1_10_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_1_10_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1_10_Closed_Text.style.display='none'; Codehighlighter1_1_10_Open_Image.style.display='inline'; Codehighlighter1_1_10_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top><span style="COLOR: #000000">&nbsp;</span><span id=Codehighlighter1_1_10_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id=Codehighlighter1_1_10_Open_Text><span style="COLOR: #808080">///</span><span style="COLOR: #008000">&nbsp;Logic</span><span style="COLOR: #808080"></span></span><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;EventNotify<br><img id=Codehighlighter1_31_101_Open_Image onclick="this.style.display='none'; Codehighlighter1_31_101_Open_Text.style.display='none'; Codehighlighter1_31_101_Closed_Image.style.display='inline'; Codehighlighter1_31_101_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_31_101_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_31_101_Closed_Text.style.display='none'; Codehighlighter1_31_101_Open_Image.style.display='inline'; Codehighlighter1_31_101_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;</span><span id=Codehighlighter1_31_101_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_31_101_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;OnEnterRgn(&nbsp;Player&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">player,&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;rgn_id&nbsp;);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;}</span></span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img id=Codehighlighter1_106_112_Open_Image onclick="this.style.display='none'; Codehighlighter1_106_112_Open_Text.style.display='none'; Codehighlighter1_106_112_Closed_Image.style.display='inline'; Codehighlighter1_106_112_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_106_112_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_106_112_Closed_Text.style.display='none'; Codehighlighter1_106_112_Open_Image.style.display='inline'; Codehighlighter1_106_112_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;</span><span id=Codehighlighter1_106_112_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id=Codehighlighter1_106_112_Open_Text><span style="COLOR: #808080">///</span><span style="COLOR: #008000">&nbsp;UI</span><span style="COLOR: #808080"></span></span><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;EventNotifyImpl&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;EventNotify<br><img id=Codehighlighter1_158_161_Open_Image onclick="this.style.display='none'; Codehighlighter1_158_161_Open_Text.style.display='none'; Codehighlighter1_158_161_Closed_Image.style.display='inline'; Codehighlighter1_158_161_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_158_161_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_158_161_Closed_Text.style.display='none'; Codehighlighter1_158_161_Open_Image.style.display='inline'; Codehighlighter1_158_161_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;</span><span id=Codehighlighter1_158_161_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_158_161_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;}</span></span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img id=Codehighlighter1_166_175_Open_Image onclick="this.style.display='none'; Codehighlighter1_166_175_Open_Text.style.display='none'; Codehighlighter1_166_175_Closed_Image.style.display='inline'; Codehighlighter1_166_175_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_166_175_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_166_175_Closed_Text.style.display='none'; Codehighlighter1_166_175_Open_Image.style.display='inline'; Codehighlighter1_166_175_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;</span><span id=Codehighlighter1_166_175_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id=Codehighlighter1_166_175_Open_Text><span style="COLOR: #808080">///</span><span style="COLOR: #008000">&nbsp;Logic</span><span style="COLOR: #808080"></span></span><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&nbsp;GetEventNotify()</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">OnEnterRgn(&nbsp;player,&nbsp;rgn_id&nbsp;);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p style="FONT-SIZE: 10pt">&nbsp;</p>
<p style="FONT-SIZE: 10pt">但是，在代码越写越多之后，逻辑模块需要通知的事件越来越多之后，EventNotify这个类开始<br>膨胀：接口变多了、不同接口定义的参数看起来也越来越恶心了。</p>
<p style="FONT-SIZE: 10pt"><strong>改进</strong></p>
<p style="FONT-SIZE: 10pt">于是我决定将各种事件通知统一化：</p>
<p style="FONT-SIZE: 10pt">&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;Event<br><img id=Codehighlighter1_13_48_Open_Image onclick="this.style.display='none'; Codehighlighter1_13_48_Open_Text.style.display='none'; Codehighlighter1_13_48_Closed_Image.style.display='inline'; Codehighlighter1_13_48_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_13_48_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_13_48_Closed_Text.style.display='none'; Codehighlighter1_13_48_Open_Image.style.display='inline'; Codehighlighter1_13_48_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_13_48_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_13_48_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;type;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;事件类型</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;附属参数</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top></span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000">;</span></div>
<p style="FONT-SIZE: 10pt">&nbsp;</p>
<p style="FONT-SIZE: 10pt">这样，逻辑模块只需要创建事件结构，两个模块间的通信就只需要一个接口即可：</p>
<p style="FONT-SIZE: 10pt">void OnNotify( const Event &amp;event );</p>
<p style="FONT-SIZE: 10pt">但是问题又来了，不同的事件类型携带的附属参数（数据）不一样。也许，可以使用一个序列化<br>的组件，将各种数据先序列化，然后在事件处理模块对应地取数据出来。这样做总感觉有点大动<br>干戈了。当然，也可以使用C语言里的不定参数去解决，如：</p>
<p style="FONT-SIZE: 10pt">void OnNotify( long event_type, ... )</p>
<p style="FONT-SIZE: 10pt">其实，我需要的就是一个可以表面上类型一样，但其内部保存的数据却多样的东西。这样一想，<br>模块就能让事情简单化：</p>
<p style="FONT-SIZE: 10pt">&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;P1,&nbsp;typename&nbsp;P2</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Param<br><img id=Codehighlighter1_48_130_Open_Image onclick="this.style.display='none'; Codehighlighter1_48_130_Open_Text.style.display='none'; Codehighlighter1_48_130_Closed_Image.style.display='inline'; Codehighlighter1_48_130_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_48_130_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_48_130_Closed_Text.style.display='none'; Codehighlighter1_48_130_Open_Image.style.display='inline'; Codehighlighter1_48_130_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_48_130_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_48_130_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;Param(&nbsp;P1&nbsp;p1,&nbsp;P2&nbsp;p2&nbsp;)&nbsp;:&nbsp;_p1(&nbsp;p1&nbsp;),&nbsp;_p2(&nbsp;p2&nbsp;)<br><img id=Codehighlighter1_105_108_Open_Image onclick="this.style.display='none'; Codehighlighter1_105_108_Open_Text.style.display='none'; Codehighlighter1_105_108_Closed_Image.style.display='inline'; Codehighlighter1_105_108_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_105_108_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_105_108_Closed_Text.style.display='none'; Codehighlighter1_105_108_Open_Image.style.display='inline'; Codehighlighter1_105_108_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;</span><span id=Codehighlighter1_105_108_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_105_108_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;P1&nbsp;_p1;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;P2&nbsp;_p2;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;P1,&nbsp;typename&nbsp;P2</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;OnNotify(&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;event_type,&nbsp;Param</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">P1,&nbsp;P2</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;param&nbsp;);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>GetNotify()</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">OnNotify(&nbsp;ET_ENTER_RGN,&nbsp;Param</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Player</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">(&nbsp;player,&nbsp;rgn_id&nbsp;)&nbsp;);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>GetNotify()</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">OnNotify(&nbsp;ET_MOVE,&nbsp;Param</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">(&nbsp;x,&nbsp;y&nbsp;)&nbsp;);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p style="FONT-SIZE: 10pt">&nbsp;</p>
<p style="FONT-SIZE: 10pt">在上面这个例子中，虽然通过Param的包装，逻辑模块可以在事件通知里放置任意类型的数据，但<br>毕竟只支持2个参数。实际上为了实现支持多个参数（起码得有15个），还是免不了自己实现多个<br>参数的Param。</p>
<p style="FONT-SIZE: 10pt">幸亏我以前写过宏递归产生代码的东西，可以自动地生成这种情况下诸如Param1、Param2的代码。<br>如：</p>
<p style="FONT-SIZE: 10pt">&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;CREATE_PARAM(&nbsp;n&nbsp;)&nbsp;\</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">DEF_PARAM(&nbsp;n&nbsp;)</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;\<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;</span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;Param##n&nbsp;\<br><img id=Codehighlighter1_80_217_Open_Image onclick="this.style.display='none'; Codehighlighter1_80_217_Open_Text.style.display='none'; Codehighlighter1_80_217_Closed_Image.style.display='inline'; Codehighlighter1_80_217_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_80_217_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_80_217_Closed_Text.style.display='none'; Codehighlighter1_80_217_Open_Image.style.display='inline'; Codehighlighter1_80_217_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;</span><span id=Codehighlighter1_80_217_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_80_217_Open_Text><span style="COLOR: #000000">{&nbsp;\<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;DEF_PARAM_TYPE(&nbsp;n&nbsp;);&nbsp;\<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;Param##n(&nbsp;DEF_FUNC_PARAM(&nbsp;n&nbsp;)&nbsp;)&nbsp;\<br><img id=Codehighlighter1_150_188_Open_Image onclick="this.style.display='none'; Codehighlighter1_150_188_Open_Text.style.display='none'; Codehighlighter1_150_188_Closed_Image.style.display='inline'; Codehighlighter1_150_188_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_150_188_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_150_188_Closed_Text.style.display='none'; Codehighlighter1_150_188_Open_Image.style.display='inline'; Codehighlighter1_150_188_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</span><span id=Codehighlighter1_150_188_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_150_188_Open_Text><span style="COLOR: #000000">{&nbsp;\<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;DEF_MEM_VAR_ASSIGN(&nbsp;n&nbsp;);&nbsp;\<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">&nbsp;\<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;DEF_VAR_DEF(&nbsp;n&nbsp;);&nbsp;\<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;CREATE_PARAM(&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;CREATE_PARAM(&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">&nbsp;);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p style="FONT-SIZE: 10pt">&nbsp;</p>
<p style="FONT-SIZE: 10pt">即可生成Param1和Param2的版本。其实这样定义了Param1、Param2的东西之后，又使得OnNotify<br>的参数不是特定的了。虽然可以把Param也泛化，但是在逻辑层写过多的模板代码，总感觉不好。</p>
<p style="FONT-SIZE: 10pt">于是又想到以前写的一个东西，可以把各种类型包装成一种类型---对于外界而言：any。any在<br>boost中有提到，我只是实现了个简单的版本。any的大致实现手法就是在内部通过多态机制将各<br>种类型在某种程度上隐藏，如：</p>
<p style="FONT-SIZE: 10pt">&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;base_type<br><img id=Codehighlighter1_32_169_Open_Image onclick="this.style.display='none'; Codehighlighter1_32_169_Open_Text.style.display='none'; Codehighlighter1_32_169_Closed_Image.style.display='inline'; Codehighlighter1_32_169_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_32_169_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_32_169_Closed_Text.style.display='none'; Codehighlighter1_32_169_Open_Image.style.display='inline'; Codehighlighter1_32_169_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_32_169_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_32_169_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">base_type()<br><img id=Codehighlighter1_95_109_Open_Image onclick="this.style.display='none'; Codehighlighter1_95_109_Open_Text.style.display='none'; Codehighlighter1_95_109_Closed_Image.style.display='inline'; Codehighlighter1_95_109_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_95_109_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_95_109_Closed_Text.style.display='none'; Codehighlighter1_95_109_Open_Image.style.display='inline'; Codehighlighter1_95_109_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_95_109_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_95_109_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;base_type&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">clone()&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;_Tp</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;var_holder&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;base_type<br><img id=Codehighlighter1_265_600_Open_Image onclick="this.style.display='none'; Codehighlighter1_265_600_Open_Text.style.display='none'; Codehighlighter1_265_600_Closed_Image.style.display='inline'; Codehighlighter1_265_600_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_265_600_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_265_600_Closed_Text.style.display='none'; Codehighlighter1_265_600_Open_Image.style.display='inline'; Codehighlighter1_265_600_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_265_600_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_265_600_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;_Tp&nbsp;type;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;var_holder</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">type</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;self;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var_holder(&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;type&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">t&nbsp;)&nbsp;:&nbsp;_t(&nbsp;t&nbsp;)<br><img id=Codehighlighter1_434_448_Open_Image onclick="this.style.display='none'; Codehighlighter1_434_448_Open_Text.style.display='none'; Codehighlighter1_434_448_Closed_Image.style.display='inline'; Codehighlighter1_434_448_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_434_448_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_434_448_Closed_Text.style.display='none'; Codehighlighter1_434_448_Open_Image.style.display='inline'; Codehighlighter1_434_448_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_434_448_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_434_448_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;base_type&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">clone()&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"><br><img id=Codehighlighter1_500_553_Open_Image onclick="this.style.display='none'; Codehighlighter1_500_553_Open_Text.style.display='none'; Codehighlighter1_500_553_Closed_Image.style.display='inline'; Codehighlighter1_500_553_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_500_553_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_500_553_Closed_Text.style.display='none'; Codehighlighter1_500_553_Open_Image.style.display='inline'; Codehighlighter1_500_553_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_500_553_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_500_553_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;self(&nbsp;_t&nbsp;);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type&nbsp;_t;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p style="FONT-SIZE: 10pt"><br>这样，any类通过一个base_type类，利用C++多态机制即可将类型隐藏于var_holder里。那么，<br>最终的事件通知接口成为下面的样子：</p>
<p style="FONT-SIZE: 10pt">void OnNotify( long type, any data );</p>
<p style="FONT-SIZE: 10pt">OnNotify( ET_ENTER_RGN, any( create_param( player, rgn_id ) ) );其中，create_param<br>是一个辅助函数，用于创建各种Param对象。</p>
<p style="FONT-SIZE: 10pt">事实上，实现各种ParamN版本，让其名字不一样其实有点不妥。还有一种方法可以让Param的名字<br>只有一个，那就是模板偏特化。例如：</p>
<p style="FONT-SIZE: 10pt">&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;_Tp</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;Param;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>template&nbsp;</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;Param</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">()</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;P1</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;Param</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">(P1)</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;P1,&nbsp;typename&nbsp;P2</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;Param</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">(P1,P2)</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p style="FONT-SIZE: 10pt">&nbsp;</p>
<p style="FONT-SIZE: 10pt">这种方法主要是通过组合出一种函数类型，来实现偏特化。因为我觉得构造一个函数类型给主模版，<br>并不是一种合情理的事情。但是，即使使用偏特化来让Param名字看起来只有一个，但对于不同的<br>实例化版本，还是不同的类型，所以还是需要any来包装。</p>
<p style="FONT-SIZE: 10pt"><strong>实际使用</strong></p>
<p style="FONT-SIZE: 10pt">实际使用起来让我觉得非常赏心悦目。上面做的这些事情，实际上是做了一个不同模块间零耦合<br>通信的通道（零耦合似乎有点过激）。现在逻辑模块通知UI模块，只需要定义新的事件类型，在<br>两边分别写通知和处理通知的代码即可。</p>
<p style="FONT-SIZE: 10pt">PS:<br>针对一些评论，我再解释下。其实any只是用于包装Param列表而已，这里也可以用void*，再转成<br>Param*。在这里过多地关注是用any*还是用void*其实偏离了本文的重点。本文的重点其实是Param：</p>
<p style="FONT-SIZE: 10pt">&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">OnNotify(&nbsp;NT_ENTER_RGN,&nbsp;ang(&nbsp;create_param(&nbsp;player,&nbsp;rgn_id&nbsp;)&nbsp;)&nbsp;);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;OnNotify(&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;type,&nbsp;any&nbsp;data&nbsp;)<br><img id=Codehighlighter1_106_235_Open_Image onclick="this.style.display='none'; Codehighlighter1_106_235_Open_Text.style.display='none'; Codehighlighter1_106_235_Closed_Image.style.display='inline'; Codehighlighter1_106_235_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_106_235_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_106_235_Closed_Text.style.display='none'; Codehighlighter1_106_235_Open_Image.style.display='inline'; Codehighlighter1_106_235_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_106_235_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_106_235_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;Param2</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Player</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;ParamType;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;ParamType&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">p&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;any_cast</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">ParamType</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">(&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">data&nbsp;);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;Player&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">player&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;p</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">p1;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;rgn_id&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;p</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">p2;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p style="FONT-SIZE: 10pt"><br><br><a href="http://www.cppblog.com/Files/kevinlynx/ParamList.rar"><font color=#cc6666>下载相关代码</font></a></p>
<img src ="http://www.cppblog.com/iwangchuchu/aggbug/113100.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-20 22:21 <a href="http://www.cppblog.com/iwangchuchu/archive/2010/04/20/113100.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>