﻿<?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++博客-每天早晨叫醒你的不是闹钟,而是梦想</title><link>http://www.cppblog.com/mmdengwo/</link><description /><language>zh-cn</language><lastBuildDate>Sat, 11 Apr 2026 21:19:25 GMT</lastBuildDate><pubDate>Sat, 11 Apr 2026 21:19:25 GMT</pubDate><ttl>60</ttl><item><title>C++中的返回值优化</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205819.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 10:20:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205819.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205819.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205819.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205819.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205819.html</trackback:ping><description><![CDATA[<span style="background-color: #eeeeee; color: #555555; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; line-height: 20px;">原文出自<a href="http://www.programlife.net/" style="color: #2970a6; text-decoration: none;">程序人生</a>&nbsp;&gt;&gt;&nbsp;<a href="http://www.programlife.net/cpp-return-value-optimization.html" style="color: #2970a6; text-decoration: none;">C++中的返回值优化(return value optimization)</a></span><span style="background-color: #eeeeee; color: #555555; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; line-height: 20px;"><br />返回值优化（Return Value Optimization，简称RVO），是这么一种优化机制：当函数需要返回一个对象的时候，如果自己创建一个临时对象用户返回，那么这个临时对象会消耗一个构造函数（Constructor）的调用、一个复制构造函数的调用（Copy Constructor）以及一个析构函数（Destructor）的调用的代价。而如果稍微做一点优化，就可以将成本降低到一个构造函数的代价，下面是在Visual Studio 2008的Debug模式下做的一个测试：（在GCC下测试的时候可能编译器自己进行了RVO优化，看不到两种代码的区别）<br /><br /></span><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;C++&nbsp;Return&nbsp;Value&nbsp;Optimization<br /></span><span style="color: #008080; ">&nbsp;2</span>&nbsp;<span style="color: #008000; "></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;作者：代码疯子<br /></span><span style="color: #008080; ">&nbsp;3</span>&nbsp;<span style="color: #008000; "></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;博客：</span><span style="color: #008000; text-decoration: underline; ">http://www.programlife.net/</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">&nbsp;4</span>&nbsp;<span style="color: #008000; "></span>#include&nbsp;&lt;iostream&gt;<br /><span style="color: #008080; ">&nbsp;5</span>&nbsp;<span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span>&nbsp;std;<br /><span style="color: #008080; ">&nbsp;6</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">&nbsp;7</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;Rational<br /><span style="color: #008080; ">&nbsp;8</span>&nbsp;{<br /><span style="color: #008080; ">&nbsp;9</span>&nbsp;<span style="color: #0000FF; ">public</span>:<br /><span style="color: #008080; ">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Rational(<span style="color: #0000FF; ">int</span>&nbsp;numerator&nbsp;=&nbsp;0,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;denominator&nbsp;=&nbsp;1)&nbsp;:&nbsp;<br /><span style="color: #008080; ">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n(numerator),&nbsp;d(denominator)<br /><span style="color: #008080; ">12</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /><span style="color: #008080; ">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;"Constructor&nbsp;Called<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />"&nbsp;&lt;&lt;&nbsp;endl;<br /><span style="color: #008080; ">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">15</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~Rational()<br /><span style="color: #008080; ">16</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /><span style="color: #008080; ">17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;"Destructor&nbsp;Called<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />"&nbsp;&lt;&lt;&nbsp;endl;<br /><span style="color: #008080; ">18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">19</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Rational(<span style="color: #0000FF; ">const</span>&nbsp;Rational&amp;&nbsp;rhs)<br /><span style="color: #008080; ">20</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /><span style="color: #008080; ">21</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>-&gt;d&nbsp;=&nbsp;rhs.d;<br /><span style="color: #008080; ">22</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>-&gt;n&nbsp;=&nbsp;rhs.n;<br /><span style="color: #008080; ">23</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;"Copy&nbsp;Constructor&nbsp;Called<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />"&nbsp;&lt;&lt;&nbsp;endl;<br /><span style="color: #008080; ">24</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">25</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;numerator()&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;{&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;n;&nbsp;}<br /><span style="color: #008080; ">26</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;denominator()&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;{&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;d;&nbsp;}<br /><span style="color: #008080; ">27</span>&nbsp;<span style="color: #0000FF; ">private</span>:<br /><span style="color: #008080; ">28</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;n,&nbsp;d;<br /><span style="color: #008080; ">29</span>&nbsp;};<br /><span style="color: #008080; ">30</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">31</span>&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">const&nbsp;Rational&nbsp;operator*(const&nbsp;Rational&amp;&nbsp;lhs,<br /></span><span style="color: #008080; ">32</span>&nbsp;<span style="color: #008000; "></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&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;const&nbsp;Rational&amp;&nbsp;rhs)<br /></span><span style="color: #008080; ">33</span>&nbsp;<span style="color: #008000; "></span><span style="color: #008000; ">//</span><span style="color: #008000; ">{<br /></span><span style="color: #008080; ">34</span>&nbsp;<span style="color: #008000; "></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Rational(lhs.numerator()&nbsp;*&nbsp;rhs.numerator(),<br /></span><span style="color: #008080; ">35</span>&nbsp;<span style="color: #008000; "></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lhs.denominator()&nbsp;*&nbsp;rhs.denominator());<br /></span><span style="color: #008080; ">36</span>&nbsp;<span style="color: #008000; "></span><span style="color: #008000; ">//</span><span style="color: #008000; ">}</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">37</span>&nbsp;<span style="color: #008000; "></span>&nbsp;<br /><span style="color: #008080; ">38</span>&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;Rational&nbsp;<span style="color: #0000FF; ">operator</span>*(<span style="color: #0000FF; ">const</span>&nbsp;Rational&amp;&nbsp;lhs,<br /><span style="color: #008080; ">39</span>&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;<span style="color: #0000FF; ">const</span>&nbsp;Rational&amp;&nbsp;rhs)<br /><span style="color: #008080; ">40</span>&nbsp;{<br /><span style="color: #008080; ">41</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;"-----------&nbsp;Enter&nbsp;operator*&nbsp;-----------"&nbsp;&lt;&lt;&nbsp;endl;<br /><span style="color: #008080; ">42</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Rational&nbsp;tmp(lhs.numerator()&nbsp;*&nbsp;rhs.numerator(),<br /><span style="color: #008080; ">43</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lhs.denominator()&nbsp;*&nbsp;rhs.denominator());<br /><span style="color: #008080; ">44</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;"-----------&nbsp;Leave&nbsp;operator*&nbsp;-----------"&nbsp;&lt;&lt;&nbsp;endl;<br /><span style="color: #008080; ">45</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;tmp;<br /><span style="color: #008080; ">46</span>&nbsp;}<br /><span style="color: #008080; ">47</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">48</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;main(<span style="color: #0000FF; ">int</span>&nbsp;argc,&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;**argv)<br /><span style="color: #008080; ">49</span>&nbsp;{<br /><span style="color: #008080; ">50</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Rational&nbsp;x(1,&nbsp;5),&nbsp;y(2,&nbsp;9);<br /><span style="color: #008080; ">51</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Rational&nbsp;z&nbsp;=&nbsp;x&nbsp;*&nbsp;y;<br /><span style="color: #008080; ">52</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;"calc&nbsp;result:&nbsp;"&nbsp;&lt;&lt;&nbsp;z.numerator()&nbsp;<br /><span style="color: #008080; ">53</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;&lt;&nbsp;"/"&nbsp;&lt;&lt;&nbsp;z.denominator()&nbsp;&lt;&lt;&nbsp;endl;<br /><span style="color: #008080; ">54</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">55</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br /><span style="color: #008080; ">56</span>&nbsp;}</div><span style="background-color: #eeeeee; color: #555555; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; line-height: 20px;"><br /></span><p style="margin: 0px 0px 10px; color: #555555; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; line-height: 20px; background-color: #eeeeee; padding: 0px;">函数输出截图如下：<br /><a href="http://www.programlife.net/wp-content/uploads/2011/06/non-rvo.jpg" style="color: #2970a6; text-decoration: none;"><img src="http://www.programlife.net/wp-content/uploads/2011/06/non-rvo.jpg" alt="Return Value Optimization" title="non-rvo" width="667" height="233" size-full=""  wp-image-1560"="" style="border: 0px; display: block; margin-left: auto; margin-right: auto; max-width: 723px;" /></a><br />可以看到消耗一个构造函数（Constructor）的调用、一个复制构造函数的调用（Copy Constructor）以及一个析构函数（Destructor）的调用的代价。</p><p style="margin: 0px 0px 10px; color: #555555; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; line-height: 20px; background-color: #eeeeee; padding: 0px;">而如果把operator*换成另一种形式：<br /><br /></p><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">1</span>&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;Rational&nbsp;<span style="color: #0000FF; ">operator</span>*(<span style="color: #0000FF; ">const</span>&nbsp;Rational&amp;&nbsp;lhs,<br /><span style="color: #008080; ">2</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;Rational&amp;&nbsp;rhs)<br /><span style="color: #008080; ">3</span>&nbsp;{<br /><span style="color: #008080; ">4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;Rational(lhs.numerator()&nbsp;*&nbsp;rhs.numerator(),<br /><span style="color: #008080; ">5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lhs.denominator()&nbsp;*&nbsp;rhs.denominator());<br /><span style="color: #008080; ">6</span>&nbsp;}<br /><br /><br /><br /><span style="color: #555555; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; font-size: 14px; line-height: 20px;">就只会消耗一个构造函数的成本了：</span><br style="color: #555555; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; font-size: 14px; line-height: 20px;" /><a href="http://www.programlife.net/wp-content/uploads/2011/06/rvo.jpg" style="color: #2970a6; text-decoration: none; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; font-size: 14px; line-height: 20px;"><img src="http://www.programlife.net/wp-content/uploads/2011/06/rvo.jpg" alt="返回值优化" title="rvo" width="670" height="159" size-full=""  wp-image-1561"="" style="border: 0px; display: block; margin-left: auto; margin-right: auto; max-width: 723px;" /></a></div><img src ="http://www.cppblog.com/mmdengwo/aggbug/205819.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 18:20 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205819.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Copy On Write(写时复制)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205812.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 10:15:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205812.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205812.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205812.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205812.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205812.html</trackback:ping><description><![CDATA[<span style="background-color: #eeeeee; color: #555555; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; line-height: 20px;">本文最初发表于<a href="http://www.programlife.net/" style="color: #2970a6; text-decoration: none;">程序人生</a>&nbsp;&gt;&gt;&nbsp;<a href="http://www.programlife.net/copy-on-write.html" style="color: #2970a6; text-decoration: none;">Copy On Write(写时复制)</a>&nbsp;作者：<strong><a href="http://www.programlife.net/" target="_blank" style="color: #0000ff; text-decoration: none;">代码疯子</a></strong></span><span style="background-color: #eeeeee; color: #555555; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; line-height: 20px;"><p style="margin: 0px 0px 10px; padding: 0px;">Copy On Write（写时复制）是在编程中比较常见的一个技术，面试中也会偶尔出现（好像Java中就经常有字符串写时复制的笔试题），今天在看《More Effective C++》的引用计数时就讲到了Copy On Write&#8212;&#8212;写时复制。下面简单介绍下Copy On Write(写时复制)，我们假设STL中的string支持写时复制（只是假设，具体未经考证，这里以Mircosoft Visual Studio 6.0为例，如果有兴趣，可以自己翻阅源码）</p><p style="margin: 0px 0px 10px; padding: 0px;"><strong>Copy On Write(写时复制)的原理是什么？</strong><br />有一定经验的程序员应该都知道Copy On Write(写时复制)使用了&#8220;引用计数&#8221;，会有一个变量用于保存引用的数量。当第一个类构造时，string的构造函数会根据传入的参数从堆上分配内存，当有其它类需要这块内存时，这个计数为自动累加，当有类析构时，这个计数会减一，直到最后一个类析构时，此时的引用计数为1或是0，此时，程序才会真正的Free这块从堆上分配的内存。<br />引用计数就是string类中写时才拷贝的原理！</p><p style="margin: 0px 0px 10px; padding: 0px;"><strong>什么情况下触发Copy On Write(写时复制)</strong><br />很显然，当然是在共享同一块内存的类发生内容改变时，才会发生Copy On Write(写时复制)。比如string类的[]、=、+=、+等，还有一些string类中诸如insert、replace、append等成员函数等，包括类的析构时。</p><p style="margin: 0px 0px 10px; padding: 0px;">示例代码：<br /></p><pre style="color: #333333; margin-top: 0px; margin-bottom: 0px; padding: 0px; background-image: none; border: none; width: auto; clear: none; overflow: visible; line-height: 1.333;"><span style="color: #666666;">// 作者：代码疯子</span> <br /><span style="color: #666666;">// 博客：http://www.programlife.net/</span> <br /><span style="color: #666666;">// 引用计数 &amp; 写时复制</span> <br /><span style="color: #339900;">#include &lt;iostream&gt;</span> <br /><span style="color: #339900;">#include &lt;string&gt;</span> <br /><span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span> &nbsp; <br /><span style="color: #0000ff;">int</span> main<span style="color: #008000;">(</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span> <span style="color: #000040;">**</span>argv<span style="color: #008000;">)</span> <br /><span style="color: #008000;">{</span> 	<br />&nbsp;&nbsp;&nbsp;string sa <span style="color: #000080;">=</span> <span style="color: #ff0000;">"Copy on write"</span><span style="color: #008080;">;</span> 	<br />&nbsp;&nbsp;&nbsp;string sb <span style="color: #000080;">=</span> sa<span style="color: #008080;">;</span> 	<br />&nbsp;&nbsp;&nbsp;string sc <span style="color: #000080;">=</span> sb<span style="color: #008080;">;</span> 	<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000dd;">printf</span><span style="color: #008000;">(</span><span style="color: #ff0000;">"sa char buffer address: 0x%08X<span style="color: #000099; font-weight: bold;">\n</span>"</span>, sa.<span style="color: #007788;">c_str</span><span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span> 	<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000dd;">printf</span><span style="color: #008000;">(</span><span style="color: #ff0000;">"sb char buffer address: 0x%08X<span style="color: #000099; font-weight: bold;">\n</span>"</span>, sb.<span style="color: #007788;">c_str</span><span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span> 	<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000dd;">printf</span><span style="color: #008000;">(</span><span style="color: #ff0000;">"sc char buffer address: 0x%08X<span style="color: #000099; font-weight: bold;">\n</span>"</span>, sc.<span style="color: #007788;">c_str</span><span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span> &nbsp; 	<br />&nbsp;&nbsp;&nbsp;sc <span style="color: #000080;">=</span> <span style="color: #ff0000;">"Now writing..."</span><span style="color: #008080;">;</span> 	<span style="color: #0000dd;">printf</span><span style="color: #008000;">(</span><span style="color: #ff0000;">"After writing sc:<span style="color: #000099; font-weight: bold;">\n</span>"</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span> 	<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000dd;">printf</span><span style="color: #008000;">(</span><span style="color: #ff0000;">"sa char buffer address: 0x%08X<span style="color: #000099; font-weight: bold;">\n</span>"</span>, sa.<span style="color: #007788;">c_str</span><span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span> 	<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000dd;">printf</span><span style="color: #008000;">(</span><span style="color: #ff0000;">"sb char buffer address: 0x%08X<span style="color: #000099; font-weight: bold;">\n</span>"</span>, sb.<span style="color: #007788;">c_str</span><span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span> 	<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000dd;">printf</span><span style="color: #008000;">(</span><span style="color: #ff0000;">"sc char buffer address: 0x%08X<span style="color: #000099; font-weight: bold;">\n</span>"</span>, sc.<span style="color: #007788;">c_str</span><span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span> &nbsp; 	<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> <br /><span style="color: #008000;">}</span></pre><div style="margin: 0px 0px 10px; overflow-x: auto; overflow-y: hidden; width: 723px; background-color: #f7f7f7; border: 1px solid #cccccc;"><span style="background-color: #eeeeee;">输出结果如下（VC 6.0）：</span></div><p style="margin: 0px 0px 10px; padding: 0px;"><a href="http://www.programlife.net/wp-content/uploads/2011/09/Copy-On-Write.jpg" style="color: #2970a6; text-decoration: none;"><img src="http://www.programlife.net/wp-content/uploads/2011/09/Copy-On-Write.jpg" alt="Copy On Write（写时复制）" title="Copy-On-Write" width="613" height="187" size-full=""  wp-image-1777"="" style="border: 0px; display: block; margin-left: auto; margin-right: auto; max-width: 723px;" /></a><br />可以看到，VC6里面的string是支持写时复制的，但是我的Visual Studio 2008就不支持这个特性（Debug和Release都是）：<br /><a href="http://www.programlife.net/wp-content/uploads/2011/09/Copy-On-Write-VS2008.jpg" style="color: #2970a6; text-decoration: none;"><img src="http://www.programlife.net/wp-content/uploads/2011/09/Copy-On-Write-VS2008.jpg" alt="Visual Studio 2008不支持Copy On Write（写时复制）" title="Copy-On-Write-VS2008" width="613" height="162" size-full=""  wp-image-1778"="" style="border: 0px; display: block; margin-left: auto; margin-right: auto; max-width: 723px;" /></a></p><p style="margin: 0px 0px 10px; padding: 0px;">拓展阅读：（摘自《Windows Via C/C++》5th Edition，不想看英文可以看中文的PDF，中文版第442页）<br /><a href="http://www.programlife.net/copy-on-write.html" target="_blank" style="color: #0000ff; text-decoration: none;">Static Data Is Not Shared by Multiple Instances of an Executable or a DLL</a></p></span><img src ="http://www.cppblog.com/mmdengwo/aggbug/205812.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 18:15 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205812.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux安装CodeBlocksSVN最新版</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205810.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 10:10:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205810.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205810.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205810.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205810.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205810.html</trackback:ping><description><![CDATA[<a href="http://apt.jenslody.de/" title="http://apt.jenslody.de/" target="_blank" style="color: #002d93; text-decoration: none; font-family: simsun; line-height: 23px;">http://apt.jenslody.de/</a><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><img src="http://hi.csdn.net/attachment/201110/30/3362235_1319944131TwC8.png" alt="" style="border: 0px; max-width: 100%; color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;"># 打开软件源配置文件添加下面5行</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">sudo gedit /etc/apt/sources.list</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">deb http://apt.jenslody.de/ any main</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">deb-src http://apt.jenslody.de/ any main</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">deb http://apt.jenslody.de/ any release</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">deb-src http://apt.jenslody.de/ any release</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">deb http://apt.wxwidgets.org/ lenny-wx main</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;"># 更新软件源配置文件 和 安装Key</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">sudo apt-get update</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">sudo apt-get install jens-lody-debian-keyring</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">wget -q http://apt.wxwidgets.org/key.asc -O- | sudo apt-key add -</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">这样只是把软件源家进去了，并没有安装好，所以还要输入安装命令</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;"># 然后输入下面这个命令开始安装 codeblocks</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">sudo apt-get install codeblocks</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><img src="http://hi.csdn.net/attachment/201110/30/3362235_131994413369ql.png" alt="" style="border: 0px; max-width: 100%; color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">现在安装好，从编程软件里开启CodeBlocks了，是英文的，并且是最近几日的最版本</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><img src="http://hi.csdn.net/attachment/201110/30/3362235_13199441353iTP.png" alt="" style="border: 0px; max-width: 100%; color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;"># 你也可以直接下载 CodeBlocks 的二进制发行包，从这个URL进入</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><a href="http://apt.jenslody.de/pool/" title="http://apt.jenslody.de/pool/" target="_blank" style="color: #002d93; text-decoration: none; font-family: simsun; line-height: 23px;">http://apt.jenslody.de/pool/</a><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;"># 中文化CodeBlocks 下载这个包，语言文件 Linux下通用的</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><a href="http://srgb.googlecode.com/files/CodeBlocks_Linux_Install.zip" title="http://srgb.googlecode.com/files/CodeBlocks_Linux_Install.zip" target="_blank" style="color: #002d93; text-decoration: none; font-family: simsun; line-height: 23px;">http://srgb.googlecode.com/files/CodeBlocks_Linux_Install.zip</a><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">进入压缩包把语言文件放到桌面 '/locale/zh_CN/CodeBlocks.mo'&nbsp;&nbsp;</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">中文化 codeblocks locale/zh_CN/codeblocks.mo 里的 中文化文件放这里</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">&nbsp;'/usr/share/codeblocks/locale/zh_CN/codeblocks.mo'&nbsp;&nbsp;</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">设置权限为所有人可以访问</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><img src="http://hi.csdn.net/attachment/201110/30/3362235_1319944136E9w5.png" alt="" style="border: 0px; max-width: 100%; color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><img src="http://hi.csdn.net/attachment/201110/30/3362235_1319944137Bjcp.png" alt="" style="border: 0px; max-width: 100%; color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;"># 使用管理员权限把 语言包 locale 目录 拉到 /usr/share/codeblocks里</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">sudo nautilus /usr/share/codeblocks/</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">注意 locale 的权限可能不完整，所以 选住目录 所有者-群组-其他设定都能访问文件;</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">对包含的文件应用权限；</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">进入 /usr/share/codeblocks/locale/zh_CN/ 目录选两个文件</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">右键修改权限 所有者 和 群组 都可以读写</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><img src="http://hi.csdn.net/attachment/201110/30/3362235_13199441386fr6.png" alt="" style="border: 0px; max-width: 100%; color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><img src="http://hi.csdn.net/attachment/201110/30/3362235_131994414068gk.png" alt="" style="border: 0px; max-width: 100%; color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">现在安装的 CodeBlocks 打开是中文里，但是只有基本IDE环境，很多插件和开发包没安装</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">可以输入 sudo apt-get install codeblocks &lt;按两下TAB&gt;</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">列出没有安装的其他包， 你可以选择安装，我偷懒了</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">sudo apt-get install codeblocks* &lt;回车&gt;</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">sudo apt-get install libwxsmith* &lt;回车&gt;</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">sudo apt-get install libwxgtk2.8-dev &lt;回车&gt;</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><img src="http://hi.csdn.net/attachment/201110/30/3362235_13199441410n03.png" alt="" style="border: 0px; max-width: 100%; color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><br style="color: #333333; font-family: simsun; line-height: 23px;" /><span style="color: #333333; font-family: simsun; line-height: 23px;">现在开启CB，建立一个wx项目，编译，可以编译成功了</span><br style="color: #333333; font-family: simsun; line-height: 23px;" /><img src="http://hi.csdn.net/attachment/201110/30/3362235_1319944142tHrz.png" alt="" style="border: 0px; max-width: 100%; color: #333333; font-family: simsun; line-height: 23px;" /><img src ="http://www.cppblog.com/mmdengwo/aggbug/205810.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 18:10 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205810.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(userdata)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205809.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:50:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205809.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205809.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205809.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205809.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205809.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp; &nbsp;在Lua中可以通过自定义类型的方式与C语言代码更高效、更灵活的交互。这里我们通过一个简单完整的示例来学习一下Lua中userdata的使用方式。需要说明的是，该示例完全来自于Programming in Lua。其功能是用C程序实现一个Lua的布尔数组，以提供程序的执行效率。见下面的代码和关键性注释。 &nbsp;&nbsp;</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">  1</span> #include &lt;lua.hpp&gt; <span style="color: #008080; line-height: 1.5 !important;">  <br />  2</span> #include &lt;lauxlib.h&gt; <span style="color: #008080; line-height: 1.5 !important;">  <br />  3</span> #include &lt;lualib.h&gt; <span style="color: #008080; line-height: 1.5 !important;">  <br />  4</span> #include &lt;limits.h&gt; <span style="color: #008080; line-height: 1.5 !important;">  <br />  5</span>  <span style="color: #008080; line-height: 1.5 !important;">  <br />  6</span> <span style="color: #0000ff; line-height: 1.5 !important;">#define</span> BITS_PER_WORD (CHAR_BIT * sizeof(int)) <span style="color: #008080; line-height: 1.5 !important;">  <br />  7</span> <span style="color: #0000ff; line-height: 1.5 !important;">#define</span> I_WORD(i)     ((unsigned int)(i))/BITS_PER_WORD <span style="color: #008080; line-height: 1.5 !important;">  <br />  8</span> <span style="color: #0000ff; line-height: 1.5 !important;">#define</span> I_BIT(i)      (1 &lt;&lt; ((unsigned int)(i)%BITS_PER_WORD)) <span style="color: #008080; line-height: 1.5 !important;">  <br />  9</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  10</span> typedef <span style="color: #0000ff; line-height: 1.5 !important;">struct</span><span style="line-height: 1.5 !important;"> NumArray { </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  11</span>     <span style="color: #0000ff; line-height: 1.5 !important;">int</span><span style="line-height: 1.5 !important;"> size; </span><span style="color: #008080; line-height: 1.5 !important;"> 12</span>     unsigned <span style="color: #0000ff; line-height: 1.5 !important;">int</span> values[<span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">]; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  13</span> <span style="line-height: 1.5 !important;">} NumArray; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  14</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  15</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> newArray(lua_State*<span style="line-height: 1.5 !important;"> L) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  16</span> <span style="line-height: 1.5 !important;">{ </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  17</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">1. 检查第一个参数是否为整型。以及该参数的值是否大于等于1.</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  18</span>     <span style="color: #0000ff; line-height: 1.5 !important;">int</span> n = luaL_checkint(L,<span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  19</span>     luaL_argcheck(L, n &gt;= <span style="color: #800080; line-height: 1.5 !important;">1</span>, <span style="color: #800080; line-height: 1.5 !important;">1</span>, <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">invalid size.</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  20</span>     size_t nbytes = <span style="color: #0000ff; line-height: 1.5 !important;">sizeof</span>(NumArray) + I_WORD(n - <span style="color: #800080; line-height: 1.5 !important;">1</span>) * <span style="color: #0000ff; line-height: 1.5 !important;">sizeof</span>(<span style="color: #0000ff; line-height: 1.5 !important;">int</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  21</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">2. 参数表示Lua为userdata分配的字节数。同时将分配后的userdata对象压入栈中。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  22</span>     NumArray* a = (NumArray*<span style="line-height: 1.5 !important;">)lua_newuserdata(L,nbytes); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  23</span>     a-&gt;size =<span style="line-height: 1.5 !important;"> n; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  24</span>     <span style="color: #0000ff; line-height: 1.5 !important;">for</span> (<span style="color: #0000ff; line-height: 1.5 !important;">int</span> i = <span style="color: #800080; line-height: 1.5 !important;">0</span>; i &lt; I_WORD(n - <span style="color: #800080; line-height: 1.5 !important;">1</span>); ++<span style="line-height: 1.5 !important;">i) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  25</span>         a-&gt;values[i] = <span style="color: #800080; line-height: 1.5 !important;">0</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  26</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">获取注册表变量myarray，该key的值为metatable。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  27</span>     luaL_getmetatable(L,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">myarray</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  28</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">将userdata的元表设置为和myarray关联的table。同时将栈顶元素弹出。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  29</span>     lua_setmetatable(L,-<span style="color: #800080; line-height: 1.5 !important;">2</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  30</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  31</span> <span style="line-height: 1.5 !important;">} </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  32</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  33</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> setArray(lua_State*<span style="line-height: 1.5 !important;"> L) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  34</span> <span style="line-height: 1.5 !important;">{ </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  35</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">1. Lua传给该函数的第一个参数必须是userdata，该对象的元表也必须是注册表中和myarray关联的table。 </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  36</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">否则该函数报错并终止程序。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  37</span>     NumArray* a = (NumArray*)luaL_checkudata(L,<span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">myarray</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  38</span>     <span style="color: #0000ff; line-height: 1.5 !important;">int</span> index = luaL_checkint(L,<span style="color: #800080; line-height: 1.5 !important;">2</span>) - <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  39</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">2. 由于任何类型的数据都可以成为布尔值，因此这里使用any只是为了确保有3个参数。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  40</span>     luaL_checkany(L,<span style="color: #800080; line-height: 1.5 !important;">3</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  41</span>     luaL_argcheck(L,a != NULL,<span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">'array' expected.</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  42</span>     luaL_argcheck(L,<span style="color: #800080; line-height: 1.5 !important;">0</span> &lt;= index &amp;&amp; index &lt; a-&gt;size,<span style="color: #800080; line-height: 1.5 !important;">2</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">index out of range.</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  43</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> (lua_toboolean(L,<span style="color: #800080; line-height: 1.5 !important;">3</span><span style="line-height: 1.5 !important;">)) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  44</span>         a-&gt;values[I_WORD(index)] |=<span style="line-height: 1.5 !important;"> I_BIT(index); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  45</span>     <span style="color: #0000ff; line-height: 1.5 !important;">else</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  46</span>         a-&gt;values[I_WORD(index)] &amp;= ~<span style="line-height: 1.5 !important;">I_BIT(index); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  47</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">0</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  48</span> <span style="line-height: 1.5 !important;">} </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  49</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  50</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> getArray(lua_State*<span style="line-height: 1.5 !important;"> L) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  51</span> <span style="line-height: 1.5 !important;">{ </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  52</span>     NumArray* a = (NumArray*)luaL_checkudata(L,<span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">myarray</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  53</span>     <span style="color: #0000ff; line-height: 1.5 !important;">int</span> index = luaL_checkint(L,<span style="color: #800080; line-height: 1.5 !important;">2</span>) - <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  54</span>     luaL_argcheck(L, a != NULL, <span style="color: #800080; line-height: 1.5 !important;">1</span>, <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">'array' expected.</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  55</span>     luaL_argcheck(L, <span style="color: #800080; line-height: 1.5 !important;">0</span> &lt;= index &amp;&amp; index &lt; a-&gt;size,<span style="color: #800080; line-height: 1.5 !important;">2</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">index out of range</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  56</span>     lua_pushboolean(L,a-&gt;values[I_WORD(index)] &amp;<span style="line-height: 1.5 !important;"> I_BIT(index)); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  57</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  58</span> <span style="line-height: 1.5 !important;">} </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  59</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  60</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> getSize(lua_State*<span style="line-height: 1.5 !important;"> L) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  61</span> <span style="line-height: 1.5 !important;">{ </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  62</span>     NumArray* a = (NumArray*)luaL_checkudata(L,<span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">myarray</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  63</span>     luaL_argcheck(L,a != NULL,<span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">'array' expected.</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  64</span>     lua_pushinteger(L,a-&gt;<span style="line-height: 1.5 !important;">size); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  65</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  66</span> <span style="line-height: 1.5 !important;">} </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  67</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  68</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> array2string(lua_State*<span style="line-height: 1.5 !important;"> L) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  69</span> <span style="line-height: 1.5 !important;">{ </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  70</span>     NumArray* a = (NumArray*)luaL_checkudata(L,<span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">myarray</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  71</span>     lua_pushfstring(L,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">array(%d)</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,a-&gt;<span style="line-height: 1.5 !important;">size); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  72</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  73</span> <span style="line-height: 1.5 !important;">} </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  74</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  75</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> luaL_Reg arraylib_f [] =<span style="line-height: 1.5 !important;"> {  </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  76</span>     {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">new</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">, newArray}, </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  77</span> <span style="line-height: 1.5 !important;">    {NULL, NULL}  </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  78</span> <span style="line-height: 1.5 !important;">};  </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  79</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  80</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> luaL_Reg arraylib_m [] =<span style="line-height: 1.5 !important;"> { </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  81</span>     {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">set</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">, setArray}, </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  82</span>     {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">get</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">, getArray}, </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  83</span>     {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">size</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">, getSize}, </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  84</span>     {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">__tostring</span><span style="color: #800000; line-height: 1.5 !important;">"</span>, array2string}, <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">print(a)时Lua会调用该元方法。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  85</span> <span style="line-height: 1.5 !important;">    {NULL, NULL}  </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  86</span> <span style="line-height: 1.5 !important;">}; </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  87</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />  88</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;"> __declspec(dllexport) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  89</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> luaopen_testuserdata(lua_State*<span style="line-height: 1.5 !important;"> L) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  90</span> <span style="line-height: 1.5 !important;">{ </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  91</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">1. 创建元表，并将该元表指定给newArray函数新创建的userdata。在Lua中userdata也是以table的身份表现的。 </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  92</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">这样在调用对象函数时，可以通过验证其metatable的名称来确定参数userdata是否合法。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  93</span>     luaL_newmetatable(L,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">myarray</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  94</span>     lua_pushvalue(L,-<span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">  95</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">2. 为了实现面对对象的调用方式，需要将元表的__index字段指向自身，同时再将arraylib_m数组中的函数注册到 </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  96</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">元表中，之后基于这些注册函数的调用就可以以面向对象的形式调用了。 </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  97</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">lua_setfield在执行后会将栈顶的table弹出。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />  98</span>     lua_setfield(L,-<span style="color: #800080; line-height: 1.5 !important;">2</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">__index</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); </span><span style="color: #008080; line-height: 1.5 !important;"> <br />  99</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">将这些成员函数注册给元表，以保证Lua在寻找方法时可以定位。NULL参数表示将用栈顶的table代替第二个参数。</span>   <br /><span style="color: #008080; line-height: 1.5 !important;">  100</span> <span style="line-height: 1.5 !important;">   luaL_register(L,NULL,arraylib_m); <br /></span><span style="color: #008080; line-height: 1.5 !important;">  101</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">这里只注册的工厂方法。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">  102</span>     luaL_register(L,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">testuserdata</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">,arraylib_f); <br /></span><span style="color: #008080; line-height: 1.5 !important;">  103</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; <br /></span><span style="color: #008080; line-height: 1.5 !important;">  104</span> }</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="color: #800080; font-size: 15px;">　　轻量级userdata：&nbsp;</span><br />　　之前介绍的是full userdata，Lua还提供了另一种轻量级userdata(light userdata)。事实上，轻量级userdata仅仅表示的是C指针的值，即(void*)。由于它只是一个值，所以不用创建。如果需要将一个轻量级userdata放入栈中，调用lua_pushlightuserdata即可。full userdata和light userdata之间最大的区别来自于相等性判断，对于一个full userdata，它只是与自身相等，而light userdata则表示为一个C指针，因此，它与所有表示同一指针的light userdata相等。再有就是light userdata不会受到垃圾收集器的管理，使用时就像一个普通的整型数字一样。</p><img src ="http://www.cppblog.com/mmdengwo/aggbug/205809.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:50 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205809.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(编写C函数的技巧)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205808.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:45:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205808.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205808.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205808.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205808.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205808.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;1. 数组操作：&nbsp;&nbsp; &nbsp;在Lua中，&#8220;数组&#8221;只是table的一个别名，是指以一种特殊的方法来使用table。出于性能原因，Lua的C API为数组操作提供了专门的函数，如：&nbsp;&nbsp; &nbsp;void lua_rawgeti(lua_State* L, int index, int key);&nbsp;&nbsp...&nbsp;&nbsp;<a href='http://www.cppblog.com/mmdengwo/archive/2014/02/17/205808.html'>阅读全文</a><img src ="http://www.cppblog.com/mmdengwo/aggbug/205808.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:45 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205808.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua调用C函数)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205807.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:45:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205807.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205807.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205807.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205807.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205807.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;Lua可以调用C函数的能力将极大的提高Lua的可扩展性和可用性。对于有些和操作系统相关的功能，或者是对效率要求较高的模块，我们完全可以通过C函数来实现，之后再通过Lua调用指定的C函数。对于那些可被Lua调用的C函数而言，其接口必须遵循Lua要求的形式，即<span style="color: #0000ff;">typedef int (*lua_CFunction)(lua_State* L)</span>。简单说明一下，该函数类型仅仅包含一个表示Lua环境的指针作为其唯一的参数，实现者可以通过该指针进一步获取Lua代码中实际传入的参数。返回值是整型，表示该C函数将返回给Lua代码的返回值数量，如果没有返回值，则return 0即可。需要说明的是，C函数无法直接将真正的返回值返回给Lua代码，而是通过虚拟栈来传递Lua代码和C函数之间的调用参数和返回值的。这里我们将介绍两种Lua调用C函数的规则。<br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;1. C函数作为应用程序的一部分。</span></p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> #include &lt;stdio.h&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />2</span> #include &lt;<span style="color: #0000ff; line-height: 1.5 !important;">string</span>.h&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />3</span> #include &lt;lua.hpp&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />4</span> #include &lt;lauxlib.h&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />5</span> #include &lt;lualib.h&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />6</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />7</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">待Lua调用的C注册函数。</span> <span style="color: #008080; line-height: 1.5 !important;"> <br />8</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> add2(lua_State*<span style="line-height: 1.5 !important;"> L) </span><span style="color: #008080; line-height: 1.5 !important;"> <br />9</span> <span style="line-height: 1.5 !important;">{ <br /></span><span style="color: #008080; line-height: 1.5 !important;">10</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">检查栈中的参数是否合法，1表示Lua调用时的第一个参数(从左到右)，依此类推。 <br /></span><span style="color: #008080; line-height: 1.5 !important;">11</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">如果Lua代码在调用时传递的参数不为number，该函数将报错并终止程序的执行。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">12</span>     <span style="color: #0000ff; line-height: 1.5 !important;">double</span> op1 = luaL_checknumber(L,<span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">13</span>     <span style="color: #0000ff; line-height: 1.5 !important;">double</span> op2 = luaL_checknumber(L,<span style="color: #800080; line-height: 1.5 !important;">2</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">14</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">将函数的结果压入栈中。如果有多个返回值，可以在这里多次压入栈中。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">15</span>     lua_pushnumber(L,op1 +<span style="line-height: 1.5 !important;"> op2); <br /></span><span style="color: #008080; line-height: 1.5 !important;">16</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">返回值用于提示该C函数的返回值数量，即压入栈中的返回值数量。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">17</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; <br /></span><span style="color: #008080; line-height: 1.5 !important;">18</span> <span style="line-height: 1.5 !important;">} <br /></span><span style="color: #008080; line-height: 1.5 !important;">19</span>  <br /><span style="color: #008080; line-height: 1.5 !important;">20</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">另一个待Lua调用的C注册函数。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">21</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> sub2(lua_State*<span style="line-height: 1.5 !important;"> L) <br /></span><span style="color: #008080; line-height: 1.5 !important;">22</span> <span style="line-height: 1.5 !important;">{ <br /></span><span style="color: #008080; line-height: 1.5 !important;">23</span>     <span style="color: #0000ff; line-height: 1.5 !important;">double</span> op1 = luaL_checknumber(L,<span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">24</span>     <span style="color: #0000ff; line-height: 1.5 !important;">double</span> op2 = luaL_checknumber(L,<span style="color: #800080; line-height: 1.5 !important;">2</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">25</span>     lua_pushnumber(L,op1 -<span style="line-height: 1.5 !important;"> op2); <br /></span><span style="color: #008080; line-height: 1.5 !important;">26</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; <br /></span><span style="color: #008080; line-height: 1.5 !important;">27</span> <span style="line-height: 1.5 !important;">} <br /></span><span style="color: #008080; line-height: 1.5 !important;">28</span>  <br /><span style="color: #008080; line-height: 1.5 !important;">29</span> <span style="color: #0000ff; line-height: 1.5 !important;">const</span> <span style="color: #0000ff; line-height: 1.5 !important;">char</span>* testfunc = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">print(add2(1.0,2.0)) print(sub2(20.1,19))</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">; <br /></span><span style="color: #008080; line-height: 1.5 !important;">30</span>  <br /><span style="color: #008080; line-height: 1.5 !important;">31</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span><span style="line-height: 1.5 !important;"> main() <br /></span><span style="color: #008080; line-height: 1.5 !important;">32</span> <span style="line-height: 1.5 !important;">{ <br /></span><span style="color: #008080; line-height: 1.5 !important;">33</span>     lua_State* L =<span style="line-height: 1.5 !important;"> luaL_newstate(); <br /></span><span style="color: #008080; line-height: 1.5 !important;">34</span> <span style="line-height: 1.5 !important;">    luaL_openlibs(L); <br /></span><span style="color: #008080; line-height: 1.5 !important;">35</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">将指定的函数注册为Lua的全局函数变量，其中第一个字符串参数为Lua代码 <br /></span><span style="color: #008080; line-height: 1.5 !important;">36</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">在调用C函数时使用的全局函数名，第二个参数为实际C函数的指针。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">37</span>     lua_register(L, <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">add2</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">, add2); <br /></span><span style="color: #008080; line-height: 1.5 !important;">38</span>     lua_register(L, <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">sub2</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">, sub2); <br /></span><span style="color: #008080; line-height: 1.5 !important;">39</span>     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">在注册完所有的C函数之后，即可在Lua的代码块中使用这些已经注册的C函数了。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">40</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span><span style="line-height: 1.5 !important;"> (luaL_dostring(L,testfunc)) <br /></span><span style="color: #008080; line-height: 1.5 !important;">41</span>         printf(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">Failed to invoke.\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">42</span> <span style="line-height: 1.5 !important;">    lua_close(L); </span><span style="color: #008080; line-height: 1.5 !important;">43</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">0</span><span style="line-height: 1.5 !important;">; </span><span style="color: #008080; line-height: 1.5 !important;">44</span> }</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: 15px; color: #800080;">2. C函数库成为Lua的模块。</span><br />&nbsp;&nbsp; &nbsp;将包含C函数的代码生成库文件，如Linux的so，或Windows的DLL，同时拷贝到Lua代码所在的当前目录，或者是LUA_CPATH环境变量所指向的目录，以便于Lua解析器可以正确定位到他们。在我当前的Windows系统中，我将其copy到"C:\Program Files\Lua\5.1\clibs\"，这里包含了所有Lua可调用的C库。见如下C语言代码和关键性注释：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> #include &lt;stdio.h&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />2</span> #include &lt;<span style="color: #0000ff; line-height: 1.5 !important;">string</span>.h&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />3</span> #include &lt;lua.hpp&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />4</span> #include &lt;lauxlib.h&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />5</span> #include &lt;lualib.h&gt; <span style="color: #008080; line-height: 1.5 !important;"> <br />6</span>  <span style="color: #008080; line-height: 1.5 !important;"> <br />7</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">待注册的C函数，该函数的声明形式在上面的例子中已经给出。 </span><span style="color: #008080; line-height: 1.5 !important;"> <br />8</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">需要说明的是，该函数必须以C的形式被导出，因此extern "C"是必须的。 </span><span style="color: #008080; line-height: 1.5 !important;"> <br />9</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">函数代码和上例相同，这里不再赘述。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">10</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> add(lua_State*<span style="line-height: 1.5 !important;"> L)  <br /></span><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="line-height: 1.5 !important;">{ </span><span style="color: #008080; line-height: 1.5 !important;">12</span>     <span style="color: #0000ff; line-height: 1.5 !important;">double</span> op1 = luaL_checknumber(L,<span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">13</span>     <span style="color: #0000ff; line-height: 1.5 !important;">double</span> op2 = luaL_checknumber(L,<span style="color: #800080; line-height: 1.5 !important;">2</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">14</span>     lua_pushnumber(L,op1 +<span style="line-height: 1.5 !important;"> op2); <br /></span><span style="color: #008080; line-height: 1.5 !important;">15</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; <br /></span><span style="color: #008080; line-height: 1.5 !important;">16</span> <span style="line-height: 1.5 !important;">} <br /></span><span style="color: #008080; line-height: 1.5 !important;">17</span>  <br /><span style="color: #008080; line-height: 1.5 !important;">18</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> sub(lua_State*<span style="line-height: 1.5 !important;"> L) <br /></span><span style="color: #008080; line-height: 1.5 !important;">19</span> <span style="line-height: 1.5 !important;">{ <br /></span><span style="color: #008080; line-height: 1.5 !important;">20</span>     <span style="color: #0000ff; line-height: 1.5 !important;">double</span> op1 = luaL_checknumber(L,<span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">);<br /></span><span style="color: #008080; line-height: 1.5 !important;">21</span>     <span style="color: #0000ff; line-height: 1.5 !important;">double</span> op2 = luaL_checknumber(L,<span style="color: #800080; line-height: 1.5 !important;">2</span><span style="line-height: 1.5 !important;">); <br /></span><span style="color: #008080; line-height: 1.5 !important;">22</span>     lua_pushnumber(L,op1 -<span style="line-height: 1.5 !important;"> op2); <br /></span><span style="color: #008080; line-height: 1.5 !important;">23</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; <br /></span><span style="color: #008080; line-height: 1.5 !important;">24</span> <span style="line-height: 1.5 !important;">} <br /></span><span style="color: #008080; line-height: 1.5 !important;">25</span>  <br /><span style="color: #008080; line-height: 1.5 !important;">26</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">luaL_Reg结构体的第一个字段为字符串，在注册时用于通知Lua该函数的名字。 <br /></span><span style="color: #008080; line-height: 1.5 !important;">27</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">第一个字段为C函数指针。 <br /></span><span style="color: #008080; line-height: 1.5 !important;">28</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">结构体数组中的最后一个元素的两个字段均为NULL，用于提示Lua注册函数已经到达数组的末尾。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">29</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> luaL_Reg mylibs[] =<span style="line-height: 1.5 !important;"> {  <br /></span><span style="color: #008080; line-height: 1.5 !important;">30</span>     {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">add</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">, add}, <br /></span><span style="color: #008080; line-height: 1.5 !important;">31</span>     {<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">sub</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">, sub}, <br /></span><span style="color: #008080; line-height: 1.5 !important;">32</span> <span style="line-height: 1.5 !important;">    {NULL, NULL}  <br /></span><span style="color: #008080; line-height: 1.5 !important;">33</span> <span style="line-height: 1.5 !important;">};  <br /></span><span style="color: #008080; line-height: 1.5 !important;">34</span>  <br /><span style="color: #008080; line-height: 1.5 !important;">35</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">该C库的唯一入口函数。其函数签名等同于上面的注册函数。见如下几点说明： <br /></span><span style="color: #008080; line-height: 1.5 !important;">36</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">1. 我们可以将该函数简单的理解为模块的工厂函数。 <br /></span><span style="color: #008080; line-height: 1.5 !important;">37</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">2. 其函数名必须为luaopen_xxx，其中xxx表示library名称。Lua代码require "xxx"需要与之对应。 <br /></span><span style="color: #008080; line-height: 1.5 !important;">38</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">3. 在luaL_register的调用中，其第一个字符串参数为模块名"xxx"，第二个参数为待注册函数的数组。 <br /></span><span style="color: #008080; line-height: 1.5 !important;">39</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">4. 需要强调的是，所有需要用到"xxx"的代码，不论C还是Lua，都必须保持一致，这是Lua的约定， <br /></span><span style="color: #008080; line-height: 1.5 !important;">40</span> <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">   否则将无法调用。</span> <br /><span style="color: #008080; line-height: 1.5 !important;">41</span> <span style="color: #0000ff; line-height: 1.5 !important;">extern</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">C</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;"> __declspec(dllexport) <br /></span><span style="color: #008080; line-height: 1.5 !important;">42</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> luaopen_mytestlib(lua_State*<span style="line-height: 1.5 !important;"> L)  <br /></span><span style="color: #008080; line-height: 1.5 !important;">43</span> <span style="line-height: 1.5 !important;">{ <br /></span><span style="color: #008080; line-height: 1.5 !important;">44</span>     <span style="color: #0000ff; line-height: 1.5 !important;">const</span> <span style="color: #0000ff; line-height: 1.5 !important;">char</span>* libName = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">mytestlib</span><span style="color: #800000; line-height: 1.5 !important;">"</span><span style="line-height: 1.5 !important;">; <br /></span><span style="color: #008080; line-height: 1.5 !important;">45</span> <span style="line-height: 1.5 !important;">    luaL_register(L,libName,mylibs); <br /></span><span style="color: #008080; line-height: 1.5 !important;">46</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">1</span><span style="line-height: 1.5 !important;">; <br /></span><span style="color: #008080; line-height: 1.5 !important;">47</span> }</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 见如下Lua代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #ff00ff; line-height: 1.5 !important;">require</span> <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">mytestlib</span><span style="color: #800000; line-height: 1.5 !important;">"</span>  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">指定包名称</span> <br /><span style="color: #008080; line-height: 1.5 !important;">2</span>  <br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">在调用时，必须是package.function</span> <br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(mytestlib.add(<span style="color: #800080; line-height: 1.5 !important;">1.0</span>,<span style="color: #800080; line-height: 1.5 !important;">2.0</span><span style="line-height: 1.5 !important;">)) <br /></span><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(mytestlib.sub(<span style="color: #800080; line-height: 1.5 !important;">20.1</span>,<span style="color: #800080; line-height: 1.5 !important;">19</span>))</pre></div><img src ="http://www.cppblog.com/mmdengwo/aggbug/205807.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:45 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205807.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(C调用Lua)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205806.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:44:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205806.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205806.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205806.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205806.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205806.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;1. 基础：&nbsp;&nbsp;&nbsp; Lua的一项重要用途就是作为一种配置语言。现在从一个简单的示例开始吧。&nbsp;&nbsp;&nbsp; --这里是用Lua代码定义的窗口大小的配置信息&nbsp;&nbsp;&nbsp; width = 200&nbsp;&nbsp;&nbsp; height = 300&nbsp;&nbsp;&nbsp; 下面是读取配置信息的C/...&nbsp;&nbsp;<a href='http://www.cppblog.com/mmdengwo/archive/2014/02/17/205806.html'>阅读全文</a><img src ="http://www.cppblog.com/mmdengwo/aggbug/205806.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:44 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205806.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua-C API简介)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205805.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:44:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205805.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205805.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205805.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205805.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205805.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp; &nbsp;Lua是一种嵌入式脚本语言，即Lua不是可以单独运行的程序，在实际应用中，主要存在两种应用形式。第一种形式是，C/C++作为主程序，调用Lua代码，此时可以将Lua看做&#8220;可扩展的语言&#8221;，我们将这种应用称为&#8220;应用程序代码&#8221;。第二种形式是Lua具有控制权，而C/C++代码则作为Lua的&#8220;库代码&#8221;。在这两种形式中，都是通过Lua提供的C API完成两种语言之间的通信的。<br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 1. 基础知识：</span><br />&nbsp;&nbsp; &nbsp;C API是一组能使C/C++代码与Lua交互的函数。其中包括读写Lua全局变量、调用Lua函数、运行一段Lua代码，以及注册C函数以供Lua代码调用等。这里先给出一个简单的示例代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> #include &lt;stdio.h&gt;<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> #include &lt;<span style="color: #0000ff; line-height: 1.5 !important;">string</span>.h&gt;<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span> #include &lt;lua.hpp&gt;<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> #include &lt;lauxlib.h&gt;<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> #include &lt;lualib.h&gt;<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> main(<span style="color: #0000ff; line-height: 1.5 !important;">void</span>)<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span> {<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>     <span style="color: #0000ff; line-height: 1.5 !important;">const</span> <span style="color: #0000ff; line-height: 1.5 !important;">char</span>* buff = <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">print(\"hello\")</span><span style="color: #800000; line-height: 1.5 !important;">"</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">10</span>     <span style="color: #0000ff; line-height: 1.5 !important;">int</span> error;<br /><span style="color: #008080; line-height: 1.5 !important;">11</span>     lua_State* L = luaL_newstate();<br /><span style="color: #008080; line-height: 1.5 !important;">12</span>     luaL_openlibs(L);<br /><span style="color: #008080; line-height: 1.5 !important;">13</span> <br /><span style="color: #008080; line-height: 1.5 !important;">14</span>     error = luaL_loadbuffer(L,buff,strlen(buff),<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">line</span><span style="color: #800000; line-height: 1.5 !important;">"</span>) || lua_pcall(L,<span style="color: #800080; line-height: 1.5 !important;">0</span>,<span style="color: #800080; line-height: 1.5 !important;">0</span>,<span style="color: #800080; line-height: 1.5 !important;">0</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">15</span>     <span style="color: #0000ff; line-height: 1.5 !important;">int</span> s = lua_gettop(L);<br /><span style="color: #008080; line-height: 1.5 !important;">16</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> (error) {<br /><span style="color: #008080; line-height: 1.5 !important;">17</span>         fprintf(stderr,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%s</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,lua_tostring(L,-<span style="color: #800080; line-height: 1.5 !important;">1</span>));<br /><span style="color: #008080; line-height: 1.5 !important;">18</span>         lua_pop(L,<span style="color: #800080; line-height: 1.5 !important;">1</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">19</span>     }<br /><span style="color: #008080; line-height: 1.5 !important;">20</span>     lua_close(L);<br /><span style="color: #008080; line-height: 1.5 !important;">21</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">0</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">22</span> }</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 下面是针对以上代码给出的具体解释：<br />&nbsp;&nbsp; &nbsp;1). 上面的代码是基于我的C++工程，而非C工程，因此包含的头文件是lua.hpp，如果是C工程，可以直接包含lua.h。<br />&nbsp;&nbsp; &nbsp;2). Lua库中没有定义任何全局变量，而是将所有的状态都保存在动态结构lua_State中，后面所有的C API都需要该指针作为第一个参数。<br />&nbsp;&nbsp; &nbsp;3). luaL_openlibs函数是用于打开Lua中的所有标准库，如io库、string库等。<br />&nbsp;&nbsp; &nbsp;4). luaL_loadbuffer编译了buff中的Lua代码，如果没有错误，则返回0，同时将编译后的程序块压入虚拟栈中。<br />&nbsp;&nbsp; &nbsp;5). lua_pcall函数会将程序块从栈中弹出，并在保护模式下运行该程序块。执行成功返回0，否则将错误信息压入栈中。<br />&nbsp;&nbsp; &nbsp;6). lua_tostring函数中的-1，表示栈顶的索引值，栈底的索引值为1，以此类推。该函数将返回栈顶的错误信息，但是不会将其从栈中弹出。<br />&nbsp;&nbsp; &nbsp;7). lua_pop是一个宏，用于从虚拟栈中弹出指定数量的元素，这里的1表示仅弹出栈顶的元素。<br />&nbsp;&nbsp; &nbsp;8). lua_close用于释放状态指针所引用的资源。<br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 2. 栈：</span><br />&nbsp;&nbsp; &nbsp;在Lua和C语言之间进行数据交换时，由于两种语言之间有着较大的差异，比如Lua是动态类型，C语言是静态类型，Lua是自动内存管理，而C语言则是手动内存管理。为了解决这些问题，Lua的设计者使用了虚拟栈作为二者之间数据交互的介质。在C/C++程序中，如果要获取Lua的值，只需调用Lua的C API函数，Lua就会将指定的值压入栈中。要将一个值传给Lua时，需要先将该值压入栈，然后调用Lua的C API，Lua就会获取该值并将其从栈中弹出。为了可以将不同类型的值压入栈，以及从栈中取出不同类型的值，Lua为每种类型均设定了一个特定函数。<br />&nbsp;&nbsp; &nbsp;1). 压入元素：<br />&nbsp;&nbsp; &nbsp;Lua针对每种C类型，都有一个C API函数与之对应，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_pushnil(lua_State* L);&nbsp;&nbsp;<span style="color: #008000;">--nil值</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_pushboolean(lua_State* L, int b);&nbsp;<span style="color: #008000;">--布尔值</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_pushnumber(lua_State* L, lua_Number n);&nbsp;<span style="color: #008000;">--浮点数</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_pushinteger(lua_State* L, lua_Integer n);&nbsp;&nbsp;<span style="color: #008000;">--整型</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_pushlstring(lua_State* L, const char* s, size_t len);&nbsp;<span style="color: #008000;">--指定长度的内存数据</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_pushstring(lua_State* L, const char* s);&nbsp;&nbsp;<span style="color: #008000;">--以零结尾的字符串，其长度可由strlen得出。</span></span><br />&nbsp;&nbsp; &nbsp;对于字符串数据，Lua不会持有他们的指针，而是调用在API时生成一个内部副本，因此，即使在这些函数返回后立刻释放或修改这些字符串指针，也不会有任何问题。<br />&nbsp;&nbsp; &nbsp;在向栈中压入数据时，可以通过调用下面的函数判断是否有足够的栈空间可用，一般而言，Lua会预留20个槽位，对于普通应用来说已经足够了，除非是遇到有很多参数的函数。<br /><span style="color: #008000;"><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_checkstack(lua_State* L, int extra)</span>&nbsp;--期望得到extra数量的空闲槽位，如果不能扩展并获得，返回false。</span>&nbsp;<br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;2). 查询元素：<br />&nbsp;&nbsp; &nbsp;API使用&#8220;索引&#8221;来引用栈中的元素，第一个压入栈的为1，第二个为2，依此类推。我们也可以使用负数作为索引值，其中-1表示为栈顶元素，-2为栈顶下面的元素，同样依此类推。<br />&nbsp;&nbsp; &nbsp;Lua提供了一组特定的函数用于检查返回元素的类型，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_isboolean (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_iscfunction (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_isfunction (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_isnil (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_islightuserdata (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_isnumber (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_isstring (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_istable (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_isuserdata (lua_State *L, int index);</span><br />&nbsp;&nbsp; &nbsp;以上函数，成功返回1，否则返回0。需要特别指出的是，对于lua_isnumber而言，不会检查值是否为数字类型，而是检查值是否能转换为数字类型。<br />&nbsp;&nbsp; &nbsp;Lua还提供了一个函数lua_type，用于获取元素的类型，函数原型如下：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_type (lua_State *L, int index);</span><br />&nbsp;&nbsp; &nbsp;该函数的返回值为一组常量值，分别是：<span style="color: #0000ff;">LUA_TNIL、LUA_TNUMBER、LUA_TBOOLEAN、LUA_TSTRING、LUA_TTABLE、LUA_TFUNCTION、LUA_TUSERDATA、LUA_TTHREAD和LUA_TLIGHTUSERDATA</span>。这些常量通常用于switch语句中。<br />&nbsp;&nbsp; &nbsp;除了上述函数之外，Lua还提供了一组转换函数，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_toboolean (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;lua_CFunction lua_tocfunction (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;lua_Integer lua_tointeger (lua_State *L, int index);&nbsp;&nbsp; &nbsp;</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;const char *lua_tolstring (lua_State *L, int index, size_t *len);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;lua_Number lua_tonumber (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;const void *lua_topointer (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;const char *lua_tostring (lua_State *L, int index);</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void *lua_touserdata (lua_State *L, int index);</span><br /><span style="color: #008000;">&nbsp;&nbsp; &nbsp;--string类型返回字符串长度，table类型返回操作符'#'等同的结果，userdata类型返回分配的内存块长度。</span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;size_t lua_objlen (lua_State *L, int index);　</span><br />&nbsp;&nbsp; &nbsp;对于上述函数，如果调用失败，lua_toboolean、lua_tonumber、lua_tointeger和lua_objlen均返回0，而其他函数则返回NULL。在很多时候0不是一个很有效的用于判断错误的值，但是ANSI C没有提供其他可以表示错误的值。因此对于这些函数，在有些情况下需要先使用lua_is*系列函数判断是否类型正确，而对于剩下的函数，则可以直接通过判断返回值是否为NULL即可。<br />&nbsp;&nbsp; &nbsp;对于lua_tolstring函数返回的指向内部字符串的指针，在该索引指向的元素被弹出之后，将无法保证仍然有效。该函数返回的字符串末尾均会有一个尾部0。<br />&nbsp;&nbsp; &nbsp;下面将给出一个工具函数，可用于演示上面提到的部分函数，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> <span style="color: #0000ff; line-height: 1.5 !important;">void</span> stackDump(lua_State* L) <br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> {<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">int</span> top = lua_gettop(L);<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     <span style="color: #0000ff; line-height: 1.5 !important;">for</span> (<span style="color: #0000ff; line-height: 1.5 !important;">int</span> i = <span style="color: #800080; line-height: 1.5 !important;">1</span>; i &lt;= top; ++i) {<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>         <span style="color: #0000ff; line-height: 1.5 !important;">int</span> t = lua_type(L,i);<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>         <span style="color: #0000ff; line-height: 1.5 !important;">switch</span>(t) {<br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span>         <span style="color: #0000ff; line-height: 1.5 !important;">case</span> LUA_TSTRING:<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>             printf(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">'%s'</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,lua_tostring(L,i));<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>             <span style="color: #0000ff; line-height: 1.5 !important;">break</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">10</span>         <span style="color: #0000ff; line-height: 1.5 !important;">case</span> LUA_TBOOLEAN:<br /><span style="color: #008080; line-height: 1.5 !important;">11</span>             printf(lua_toboolean(L,i) ? <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">true</span><span style="color: #800000; line-height: 1.5 !important;">"</span> : <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">false</span><span style="color: #800000; line-height: 1.5 !important;">"</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">12</span>             <span style="color: #0000ff; line-height: 1.5 !important;">break</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">13</span>         <span style="color: #0000ff; line-height: 1.5 !important;">case</span> LUA_TNUMBER:<br /><span style="color: #008080; line-height: 1.5 !important;">14</span>             printf(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%g</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,lua_tonumber(L,i));<br /><span style="color: #008080; line-height: 1.5 !important;">15</span>             <span style="color: #0000ff; line-height: 1.5 !important;">break</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">16</span>         <span style="color: #0000ff; line-height: 1.5 !important;">default</span>:<br /><span style="color: #008080; line-height: 1.5 !important;">17</span>             printf(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%s</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,lua_typename(L,t));<br /><span style="color: #008080; line-height: 1.5 !important;">18</span>             <span style="color: #0000ff; line-height: 1.5 !important;">break</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">19</span>         }<br /><span style="color: #008080; line-height: 1.5 !important;">20</span>         printf(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">"</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">21</span>     }<br /><span style="color: #008080; line-height: 1.5 !important;">22</span>     printf(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">23</span> }</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 3). 其它栈操作函数：<br />&nbsp;&nbsp; &nbsp;除了上面给出的数据交换函数之外，Lua的C API还提供了一组用于操作虚拟栈的普通函数，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;int lua_gettop(lua_State* L);&nbsp;<span style="color: #008000;">--返回栈中元素的个数。</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_settop(lua_State* L, int index);&nbsp;<span style="color: #008000;">--将栈顶设置为指定的索引值。</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_pushvalue(lua_State* L, int index);&nbsp;<span style="color: #008000;">--将指定索引的元素副本压入栈。</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_remove(lua_State* L, int index);&nbsp;<span style="color: #008000;">--删除指定索引上的元素，其上面的元素自动下移。</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_insert(lua_State* L, int index);&nbsp;<span style="color: #008000;">--将栈顶元素插入到该索引值指向的位置。</span></span><br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;void lua_replace(lua_State* L, int index);&nbsp;<span style="color: #008000;">--弹出栈顶元素，并将该值设置到指定索引上。</span></span><br />&nbsp;&nbsp; &nbsp;Lua还提供了一个宏用于弹出指定数量的元素：<span style="color: #0000ff;">#define lua_pop(L,n)&nbsp; lua_settop(L, -(n) - 1)&nbsp;&nbsp; &nbsp;</span><br />&nbsp;&nbsp; &nbsp;见如下示例代码：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">int</span> main()<br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> {<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span>     lua_State* L = luaL_newstate();<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span>     lua_pushboolean(L,<span style="color: #800080; line-height: 1.5 !important;">1</span>);<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>     lua_pushnumber(L,<span style="color: #800080; line-height: 1.5 !important;">10</span>);<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>     lua_pushnil(L);<br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span>     lua_pushstring(L,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">hello</span><span style="color: #800000; line-height: 1.5 !important;">"</span>);<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     stackDump(L); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">true 10 nil 'hello'</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <br /><span style="color: #008080; line-height: 1.5 !important;">10</span>     lua_pushvalue(L,-<span style="color: #800080; line-height: 1.5 !important;">4</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">11</span>     stackDump(L); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">true 10 nil 'hello' true</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">12</span> <br /><span style="color: #008080; line-height: 1.5 !important;">13</span>     lua_replace(L,<span style="color: #800080; line-height: 1.5 !important;">3</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">14</span>     stackDump(L); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">true 10 true 'hello'</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">15</span> <br /><span style="color: #008080; line-height: 1.5 !important;">16</span>     lua_settop(L,<span style="color: #800080; line-height: 1.5 !important;">6</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">17</span>     stackDump(L); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">true 10 true 'hello' nil nil</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">18</span> <br /><span style="color: #008080; line-height: 1.5 !important;">19</span>     lua_remove(L,-<span style="color: #800080; line-height: 1.5 !important;">3</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">20</span>     stackDump(L); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">true 10 true nil nil</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">21</span> <br /><span style="color: #008080; line-height: 1.5 !important;">22</span>     lua_settop(L,-<span style="color: #800080; line-height: 1.5 !important;">5</span>);<br /><span style="color: #008080; line-height: 1.5 !important;">23</span>     stackDump(L); <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">true</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">24</span> <br /><span style="color: #008080; line-height: 1.5 !important;">25</span>     lua_close(L);<br /><span style="color: #008080; line-height: 1.5 !important;">26</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> <span style="color: #800080; line-height: 1.5 !important;">0</span>;<br /><span style="color: #008080; line-height: 1.5 !important;">27</span> }</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 3. C API中的错误处理：</span><br />&nbsp;&nbsp; &nbsp;1). C程序调用Lua代码的错误处理：<br />&nbsp;&nbsp; &nbsp;通常情况下，应用程序代码是以&#8220;无保护&#8221;模式运行的。因此，当Lua发现&#8220;内存不足&#8221;这类错误时，只能通过调用&#8220;紧急&#8221;函数来通知C语言程序，之后在结束应用程序。用户可通过<span style="color: #0000ff;">lua_atpanic</span>来设置自己的&#8220;紧急&#8221;函数。如果希望应用程序代码在发生Lua错误时不会退出，可通过调用<span style="color: #0000ff;">lua_pcall</span>函数以保护模式运行Lua代码。这样再发生内存错误时，lua_pcall会返回一个错误代码，并将解释器重置为一致的状态。如果要保护与Lua的C代码，可以使用<span style="color: #0000ff;">lua_cpall</span>函数，它将接受一个C函数作为参数，然后调用这个C函数。<br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;2). Lua调用C程序：<br />&nbsp;&nbsp; &nbsp;通常而言，当一个被Lua调用的C函数检测到错误时，它就应该调用<span style="color: #0000ff;">lua_error</span>，该函数会清理Lua中所有需要清理的资源，然后跳转回发起执行的那个lua_pcall，并附上一条错误信息。</p><img src ="http://www.cppblog.com/mmdengwo/aggbug/205805.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:44 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205805.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua系统库)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205804.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:43:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205804.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205804.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205804.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205804.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205804.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp; Lua为了保证高度的可移植性，因此，它的标准库仅仅提供了非常少的功能，特别是和OS相关的库。但是Lua还提供了一些扩展库，比如Posix库等。对于文件操作而言，该库仅提供了<span style="color: #0000ff;">os.rename</span>函数和<span style="color: #0000ff;">os.remove</span>函数。<br />&nbsp;&nbsp; &nbsp;<br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;1. 日期和时间：</span><br />&nbsp;&nbsp; &nbsp;在Lua中，函数<span style="color: #0000ff;">time</span>和<span style="color: #0000ff;">date</span>提供了所有的日期和时间功能。<br />&nbsp;&nbsp; &nbsp;如果不带任何参数调用time函数，它将以数字形式返回当前的日期和时间。如果以一个table作为参数，它将返回一个数字，表示该table中所描述的日期和时间。该table的有效字段如下：</p><table border="0" align="center" style="border-style: solid; border-color: silver; border-collapse: collapse; color: #000000; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px; width: 600px;"><tbody><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">字段名</span></strong></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">描述</span></strong></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">year</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">一个完整的年份</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">month</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">01-12</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">day</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">01-31</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">hour</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">00-23</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">min</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">00-59</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">sec</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">00-59</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">isdst</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">布尔值，true表示夏令时</span></td></tr></tbody></table><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">print(os.time{year = 1970, month = 1, day = 1, hour = 8, min = 0})&nbsp;<span style="color: #008000;">--北京是东八区，所以hour等于时表示UTC的0。</span></span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000;"><span style="color: #0000ff;">print(os.time())</span>&nbsp; --输出当前时间距离1970-1-1 00:00:00所经过的秒数。输出值为 1333594721</span><br />&nbsp;&nbsp;&nbsp; 函数date是time的反函数，即可以将time返回的数字值转换为更高级的可读格式，其第一个参数是格式化字符串，表示期望的日期返回格式，第二个参数是日期和时间的数字，缺省为当前日期和时间。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> dd = <span style="color: #ff00ff; line-height: 1.5 !important;">os.date</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*t</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #ff00ff; line-height: 1.5 !important;">os.time</span>())  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">如果格式化字符串为"*t"，函数将返回table形式的日期对象。</span><span style="color: #008000; line-height: 1.5 !important;">如果为"!*t"，则表示为UTC时间格式。<br /></span><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">year = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. dd.year)<br /><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">month = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. dd.month)<br /><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">day = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. dd.day)<br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">weekday = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. dd.wday)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">一个星期中的第几天，周日是第一天</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">yearday = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. dd.yday)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">一年中的第几天，1月1日是第一天</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 7</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">hour = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. dd.hour)<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">min = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. dd.min)<br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">sec = </span><span style="color: #800000; line-height: 1.5 !important;">"</span> .. dd.sec)<br /><span style="color: #008080; line-height: 1.5 !important;">10</span>     <br /><span style="color: #008080; line-height: 1.5 !important;">11</span> <span style="color: #008000; line-height: 1.5 !important;">--[[</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #008000; line-height: 1.5 !important;">year = 2012<br /></span><span style="color: #008080; line-height: 1.5 !important;">13</span> <span style="color: #008000; line-height: 1.5 !important;">month = 4<br /></span><span style="color: #008080; line-height: 1.5 !important;">14</span> <span style="color: #008000; line-height: 1.5 !important;">day = 5<br /></span><span style="color: #008080; line-height: 1.5 !important;">15</span> <span style="color: #008000; line-height: 1.5 !important;">weekday = 5<br /></span><span style="color: #008080; line-height: 1.5 !important;">16</span> <span style="color: #008000; line-height: 1.5 !important;">yearday = 96<br /></span><span style="color: #008080; line-height: 1.5 !important;">17</span> <span style="color: #008000; line-height: 1.5 !important;">hour = 11<br /></span><span style="color: #008080; line-height: 1.5 !important;">18</span> <span style="color: #008000; line-height: 1.5 !important;">min = 13<br /></span><span style="color: #008080; line-height: 1.5 !important;">19</span> <span style="color: #008000; line-height: 1.5 !important;">sec = 44<br /></span><span style="color: #008080; line-height: 1.5 !important;">20</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">]]</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; date函数的格式化标识和C运行时库中的strftime函数的标识完全相同，见下表：</p><table border="0" align="center" style="border-style: solid; border-color: silver; border-collapse: collapse; color: #000000; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px; width: 600px;"><tbody><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">关键字</span></strong></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">描述</span></strong></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%a</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">一星期中天数的缩写，如Wed</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%A</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">一星期中天数的全称，如Friday</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%b</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">月份的缩写，如Sep</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%B</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">月份的全称，如September</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%c</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">日期和时间</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%d</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">一个月中的第几天(01-31)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%H</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">24小时制中的小时数(00-23)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%I</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">12小时制中的小时数(01-12)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%j</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">一年中的第几天(001-366)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%M</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">分钟(00-59)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%m</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">月份(01-12)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%p</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">"上午(am)"或"下午(pm)"</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%S</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">秒数(00-59)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%w</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">一星期中的第几天(0--6等价于星期日--星期六)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%x</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">日期，如09/16/2010</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%X</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">时间，如23:48:20</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%y</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">两位数的年份(00-99)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%Y</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">完整的年份(2012)</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">%%</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">字符'%'</span></td></tr></tbody></table><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">print(os.date("%Y-%m-%d"))&nbsp;<span style="color: #008000;">&nbsp;--输出2012-04-05</span></span><br />&nbsp;&nbsp;&nbsp; 函数os.clock()返回CPU时间的描述，通常用于计算一段代码的执行效率。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> x = <span style="color: #ff00ff; line-height: 1.5 !important;">os.clock</span>()<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> s = <span style="color: #800080; line-height: 1.5 !important;">0</span><br /><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> i = <span style="color: #800080; line-height: 1.5 !important;">1</span>, <span style="color: #800080; line-height: 1.5 !important;">10000000</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span> <br /><span style="color: #008080; line-height: 1.5 !important;">4</span>     s = s + i <br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">6</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">string.format</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">elapsed time: %.2f\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>, <span style="color: #ff00ff; line-height: 1.5 !important;">os.clock</span>() - x))<br /><span style="color: #008080; line-height: 1.5 !important;">7</span> <br /><span style="color: #008080; line-height: 1.5 !important;">8</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">输出结果为：</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">9</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">elapsed time: 0.21    </span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;2. 其他系统调用：</span><br />&nbsp;&nbsp; &nbsp;函数<span style="color: #0000ff;">os.exit()</span>可中止当前程序的执行。函数<span style="color: #0000ff;">os.getenv()</span>可获取一个环境变量的值。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;print(os.getenv("PATH"))&nbsp;&nbsp;<span style="color: #008000;">--如果环境变量不存在，返回nil。</span></span><br />&nbsp;&nbsp; &nbsp;<span style="color: #0000ff;">os.execute</span>函数用于执行和操作系统相关的命令，如：<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">&nbsp;os.execute("mkdir " .. "hello")</span></p><img src ="http://www.cppblog.com/mmdengwo/aggbug/205804.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:43 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205804.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Step By Step(Lua输入输出库)</title><link>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205803.html</link><dc:creator>沛沛</dc:creator><author>沛沛</author><pubDate>Mon, 17 Feb 2014 09:43:00 GMT</pubDate><guid>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205803.html</guid><wfw:comment>http://www.cppblog.com/mmdengwo/comments/205803.html</wfw:comment><comments>http://www.cppblog.com/mmdengwo/archive/2014/02/17/205803.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mmdengwo/comments/commentRss/205803.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mmdengwo/services/trackbacks/205803.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp; I/O库为文件操作提供了两种不同的模型，简单模型和完整模型。简单模型假设一个当前输入文件和一个当前输出文件，他的I/O操作均作用于这些文件。完整模型则使用显式的文件句柄，并将所有的操作定义为文件句柄上的方法。<br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp; &nbsp;1. 简单模型：</span><br />&nbsp;&nbsp; &nbsp;I/O库会将进程标准输入输出作为其缺省的输入文件和输出文件。我们可以通过<span style="color: #0000ff;">io.input(filename)</span>和<span style="color: #0000ff;">io.output(filename)</span>这两个函数来改变当前的输入输出文件。<br />&nbsp;&nbsp; &nbsp;1). io.write函数：<br />&nbsp;&nbsp; &nbsp;函数原型为io.write(...)。该函数将所有参数顺序的写入到当前输出文件中。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;io.write("hello","world")&nbsp;<span style="color: #008000;">--写出的内容为helloworld</span></span><br /><br />&nbsp;&nbsp; &nbsp;2). io.read函数：<br />&nbsp;&nbsp; &nbsp;下表给出了该函数参数的定义和功能描述：</p><table border="0" align="center" style="border-style: solid; border-color: silver; border-collapse: collapse; color: #000000; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px; width: 600px;"><tbody><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">参数字符串</span></strong></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><strong><span style="color: #0000ff;">含义</span></strong></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">"*all"</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">读取整个文件</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">"*line"</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">读取下一行</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">"*number"</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">读取一个数字</span></td></tr><tr><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">&lt;num&gt;</span></td><td style="border-style: solid; border-color: silver; border-collapse: collapse; padding: 3px;"><span style="color: #0000ff;">读取一个不超过&lt;num&gt;个字符的字符串</span></td></tr></tbody></table><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 调用<span style="color: #0000ff;">io.read("*all")</span>会读取当前输入文件的所有内容，以当前位置作为开始。如果当前位置处于文件的末尾，或者文件为空，那个该调用返回一个空字符串。由于Lua可以高效的处理长字符串，因此在Lua中可以先将数据从文件中完整读出，之后在通过Lua字符串库提供的函数进行各种处理。<br />&nbsp;&nbsp; &nbsp;调用<span style="color: #0000ff;">io.read("*line")</span>会返回当前文件的下一行，但不包含换行符。当到达文件末尾时，该调用返回nil。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> count = <span style="color: #800080; line-height: 1.5 !important;">1</span>,<span style="color: #ff00ff; line-height: 1.5 !important;">math.huge</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> line = <span style="color: #ff00ff; line-height: 1.5 !important;">io.read</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*line</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">如果不传参数，缺省值也是"*line"</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> line == <span style="color: #0000ff; line-height: 1.5 !important;">nil</span> <span style="color: #0000ff; line-height: 1.5 !important;">then</span> <br /><span style="color: #008080; line-height: 1.5 !important;">4</span>         <span style="color: #0000ff; line-height: 1.5 !important;">break</span><br /><span style="color: #008080; line-height: 1.5 !important;">5</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">6</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">io.write</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">string.format</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%6d  </span><span style="color: #800000; line-height: 1.5 !important;">"</span>,count),line,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">7</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 如果只是为了迭代文件中的所有行，可以使用<span style="color: #0000ff;">io.lines</span>函数，以迭代器的形式访问文件中的每一行数据，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> lines = {}<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> line <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">io.lines</span>() <span style="color: #0000ff; line-height: 1.5 !important;">do</span>   <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">通过迭代器访问每一个数据</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">3</span>     lines[#lines + <span style="color: #800080; line-height: 1.5 !important;">1</span>] = line<br /><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">5</span> <span style="color: #ff00ff; line-height: 1.5 !important;">table.sort</span>(lines)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">排序，Lua标准库的table库提供的函数。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">6</span> <span style="color: #0000ff; line-height: 1.5 !important;">for</span> _,l <span style="color: #0000ff; line-height: 1.5 !important;">in</span> <span style="color: #ff00ff; line-height: 1.5 !important;">ipairs</span>(lines) <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">7</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">io.write</span>(l,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">8</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 调用<span style="color: #0000ff;">io.read("*number")</span>会从当前输入文件中读取一个数字。此时read将直接返回一个数字，而不是字符串。"*number"选项会忽略数字前面所有的空格，并且能处理像-3、+5.2这样的数字格式。如果当前读取的数据不是合法的数字，read返回nil。在调用read是可以指定多个选项，函数会根据每个选项参数返回相应的内容。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #008000; line-height: 1.5 !important;">--[[</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #008000; line-height: 1.5 !important;">    6.0  -3.23   1000<br /></span><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #008000; line-height: 1.5 !important;">    ... ...<br /></span><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #008000; line-height: 1.5 !important;">    下面的代码读取注释中的数字<br /></span><span style="color: #008080; line-height: 1.5 !important;"> 5</span> <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">]]</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span> <span style="color: #0000ff; line-height: 1.5 !important;">while</span> <span style="color: #0000ff; line-height: 1.5 !important;">true</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> n1,n2,n3 = <span style="color: #ff00ff; line-height: 1.5 !important;">io.read</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*number</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*number</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*number</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> <span style="color: #0000ff; line-height: 1.5 !important;">not</span> n1 <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>         <span style="color: #0000ff; line-height: 1.5 !important;">break</span><br /><span style="color: #008080; line-height: 1.5 !important;">10</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">11</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">math.max</span>(n1,n2,n3))<br /><span style="color: #008080; line-height: 1.5 !important;">12</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 调用<span style="color: #0000ff;">io.read(&lt;num&gt;)</span>会从输入文件中最多读取n个字符，如果读不到任何字符，返回nil。否则返回读取到的字符串。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">while</span> <span style="color: #0000ff; line-height: 1.5 !important;">true</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> block = <span style="color: #ff00ff; line-height: 1.5 !important;">io.read</span>(<span style="color: #800080; line-height: 1.5 !important;">2</span>^<span style="color: #800080; line-height: 1.5 !important;">13</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> <span style="color: #0000ff; line-height: 1.5 !important;">not</span> block <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">4</span>         <span style="color: #0000ff; line-height: 1.5 !important;">break</span><br /><span style="color: #008080; line-height: 1.5 !important;">5</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">6</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">io.write</span>(block)<br /><span style="color: #008080; line-height: 1.5 !important;">7</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp;<span style="color: #0000ff;">&nbsp;io.read(0)</span>是一种特殊的情况，用于检查是否到达了文件的末尾。如果没有到达，返回空字符串，否则nil。<br /><br /><span style="color: #800080; font-size: 15px;">&nbsp;&nbsp;&nbsp; 2. 完整I/O模型：</span><br />&nbsp;&nbsp; &nbsp;Lua中完整I/O模型的使用方式非常类似于C运行时库的文件操作函数，它们都是基于文件句柄的。<br />&nbsp;&nbsp; &nbsp;1). 通过<span style="color: #0000ff;">io.open</span>函数打开指定的文件，并且在参数中给出对该文件的打开模式，其中<span style="color: #0000ff;">"r"</span>表示读取，<span style="color: #0000ff;">"w"</span>表示覆盖写入，即先删除文件原有的内容，<span style="color: #0000ff;">"a"</span>表示追加式写入，<span style="color: #0000ff;">"b"</span>表示以二进制的方式打开文件。在成功打开文件后，该函数将返回表示该文件的句柄，后面所有基于该文件的操作，都需要将该句柄作为参数传入。如果打开失败，返回nil。其中错误信息由该函数的第二个参数返回，如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;assert(io.open(filename,mode))&nbsp;&nbsp;<span style="color: #008000;">--如果打开失败，assert将打印第二个参数给出的错误信息。</span></span><br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;2). 文件读写函数<span style="color: #0000ff;">read/write</span>。这里需要用到冒号语法，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> f = <span style="color: #ff00ff; line-height: 1.5 !important;">assert</span>(<span style="color: #ff00ff; line-height: 1.5 !important;">io.open</span>(filename,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">r</span><span style="color: #800000; line-height: 1.5 !important;">"</span>))<br /><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> t = f:read(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*all</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">对于read而言，其参数完全等同于简单模型下read的参数。</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">3</span> f:close()</pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 此外，I/O库还提供了3个预定义的文件句柄，即<span style="color: #0000ff;">io.stdin(标准输入)、io.stdout(标准输出)、io.stderr(标准错误输出)</span>。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;io.stderr:write("This is an error message.")</span><br />&nbsp;&nbsp; &nbsp;事实上，我们也可以混合使用简单模式和完整模式，如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> temp = <span style="color: #ff00ff; line-height: 1.5 !important;">io.input</span>()   <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">将当前文件句柄保存</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">2</span> <span style="color: #ff00ff; line-height: 1.5 !important;">io.input</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">newInputfile</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">打开新的输入文件</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">3</span> <span style="color: #ff00ff; line-height: 1.5 !important;">io.input</span>():close()        <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">关闭当前文件</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">4</span> <span style="color: #ff00ff; line-height: 1.5 !important;">io.input</span>(temp)            <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">恢复原来的输入文件</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br />&nbsp;&nbsp;&nbsp; 3). 性能小技巧：<br />&nbsp;&nbsp; &nbsp;由于一次性读取整个文件比逐行读取要快一些，但对于较大的文件，这样并不可行，因此Lua提供了一种折中的方式，即一次读取指定字节数量的数据，如果当前读取中的最后一行不是完整的一行，可通过该方式将该行的剩余部分也一并读入，从而保证本次读取的数据均为整行数据，以便于上层逻辑的处理。如：<br /><span style="color: #0000ff;">&nbsp;&nbsp; &nbsp;local lines,rest = f:read(BUFSIZE,"*line")&nbsp;<span style="color: #008000;">--rest变量包含最后一行中没有读取的部分。</span></span><br />&nbsp;&nbsp; &nbsp;下面是Shell中wc命令的一个简单实现。</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;"> 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> BUFSIZE = <span style="color: #800080; line-height: 1.5 !important;">8192</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 2</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> f = <span style="color: #ff00ff; line-height: 1.5 !important;">io.input</span>(arg[<span style="color: #800080; line-height: 1.5 !important;">1</span>])  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">打开输入文件</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 3</span> <span style="color: #0000ff; line-height: 1.5 !important;">local</span> cc, lc, wc, = <span style="color: #800080; line-height: 1.5 !important;">0</span>, <span style="color: #800080; line-height: 1.5 !important;">0</span>, <span style="color: #800080; line-height: 1.5 !important;">0</span>  <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">分别计数字符、行和单词    </span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;"> 4</span> <span style="color: #0000ff; line-height: 1.5 !important;">while</span> <span style="color: #0000ff; line-height: 1.5 !important;">true</span> <span style="color: #0000ff; line-height: 1.5 !important;">do</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 5</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> lines,rest = f:read(BUFSIZE,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">*line</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;"> 6</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> <span style="color: #0000ff; line-height: 1.5 !important;">not</span> lines <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 7</span>         <span style="color: #0000ff; line-height: 1.5 !important;">break</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 8</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;"> 9</span>     <span style="color: #0000ff; line-height: 1.5 !important;">if</span> rest <span style="color: #0000ff; line-height: 1.5 !important;">then</span><br /><span style="color: #008080; line-height: 1.5 !important;">10</span>         lines = lines .. rest .. <span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span><br /><span style="color: #008080; line-height: 1.5 !important;">11</span>     <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">12</span>     cc = cc + #lines<br /><span style="color: #008080; line-height: 1.5 !important;">13</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">计算单词数量</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">14</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> _, t = <span style="color: #ff00ff; line-height: 1.5 !important;">string.gsub</span>(lines.<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">%S+</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">""</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">15</span>     wc = wc + t<br /><span style="color: #008080; line-height: 1.5 !important;">16</span>     <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">计算行数</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">17</span>     _,t = <span style="color: #ff00ff; line-height: 1.5 !important;">string.gsub</span>(line,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">\n</span><span style="color: #800000; line-height: 1.5 !important;">"</span>)<br /><span style="color: #008080; line-height: 1.5 !important;">18</span>     lc = lc + t<br /><span style="color: #008080; line-height: 1.5 !important;">19</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span><br /><span style="color: #008080; line-height: 1.5 !important;">20</span> <span style="color: #ff00ff; line-height: 1.5 !important;">print</span>(lc,wc,cc)</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1d58d1; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><br />&nbsp;&nbsp;&nbsp; 4). 其它文件操作：<br />&nbsp;&nbsp; &nbsp;如<span style="color: #0000ff;">io.flush</span>函数会将io缓存中的数据刷新到磁盘文件上。<span style="color: #0000ff;">io.close</span>函数将关闭当前打开的文件。<span style="color: #0000ff;">io.seek</span>函数用于设置或获取当前文件的读写位置，其函数原型为<span style="color: #0000ff;">f:seek(whence,offset)</span>，如果whence的值为<span style="color: #0000ff;">"set"</span>，offset的值则表示为相对于文件起始位置的偏移量。如为<span style="color: #0000ff;">"cur"(默认值)</span>,offset则为相对于当前位置的偏移量，如为<span style="color: #0000ff;">"end"</span>，则为相对于文件末尾的偏移量。函数的返回值与whence参数无关，总是返回文件的当前位置，即相对于文件起始处的偏移字节数。offset的默认值为0。如：</p><div style="background-color: #f5f5f5; border: 1px solid #cccccc; padding: 5px; overflow: auto; margin: 5px 0px; max-width: 900px; line-height: 18px; font-family: 'Courier New' !important;"><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #008080; line-height: 1.5 !important;">1</span> <span style="color: #0000ff; line-height: 1.5 !important;">function</span> fsize(file)<br /><span style="color: #008080; line-height: 1.5 !important;">2</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> current = <span style="color: #ff00ff; line-height: 1.5 !important;">file:seek</span>()   <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">获取当前位置</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">3</span>     <span style="color: #0000ff; line-height: 1.5 !important;">local</span> size = <span style="color: #ff00ff; line-height: 1.5 !important;">file:seek</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">end</span><span style="color: #800000; line-height: 1.5 !important;">"</span>) <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">获取文件大小</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">4</span>     <span style="color: #ff00ff; line-height: 1.5 !important;">file:seek</span>(<span style="color: #800000; line-height: 1.5 !important;">"</span><span style="color: #800000; line-height: 1.5 !important;">set</span><span style="color: #800000; line-height: 1.5 !important;">"</span>,current)      <span style="color: #008000; line-height: 1.5 !important;">--</span><span style="color: #008000; line-height: 1.5 !important;">恢复原有的当前位置</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span><span style="color: #008080; line-height: 1.5 !important;">5</span>     <span style="color: #0000ff; line-height: 1.5 !important;">return</span> size<br /><span style="color: #008080; line-height: 1.5 !important;">6</span> <span style="color: #0000ff; line-height: 1.5 !important;">end</span></pre></div><p style="margin-top: 10px; margin-bottom: 10px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;">&nbsp;&nbsp;&nbsp; 最后需要指出的是，如果发生错误，所有这些函数均返回nil和一条错误信息。</p><img src ="http://www.cppblog.com/mmdengwo/aggbug/205803.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mmdengwo/" target="_blank">沛沛</a> 2014-02-17 17:43 <a href="http://www.cppblog.com/mmdengwo/archive/2014/02/17/205803.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>