??xml version="1.0" encoding="utf-8" standalone="yes"?>99久久精品这里只有精品,久久不见久久见免费视频7,色欲综合久久躁天天躁http://www.shnenglu.com/Leaf/category/10585.html~~zh-cnFri, 14 Jun 2013 21:23:50 GMTFri, 14 Jun 2013 21:23:50 GMT60镜面反射矩阵推导http://www.shnenglu.com/Leaf/archive/2013/06/15/201017.htmlRender DonkeyRender DonkeyFri, 14 Jun 2013 16:48:00 GMThttp://www.shnenglu.com/Leaf/archive/2013/06/15/201017.htmlhttp://www.shnenglu.com/Leaf/comments/201017.htmlhttp://www.shnenglu.com/Leaf/archive/2013/06/15/201017.html#Feedback0http://www.shnenglu.com/Leaf/comments/commentRss/201017.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/201017.html最q公司游戏正在准备上U,所以FlasCC也就没有研究了,偶尔有闲功夫Q也是玩?DMAX和UNITY3D?感觉不会3DMAXQ是一U局限?/p>

回到主题Q记录一下镜面反矩늚推导?/p>

在用Irrlicht和RTT做镜面效果的时候,用到了反矩c?是需要把摄相机镜像,渲染一个RTQ脓到镜面模型上。这个其实还U结了许久,因ؓ之前做水面渲染的时候,水面是^的,很好计算摄相机在水面以下的位|?但是换成镜面Q就不一样了Q因为镜面可能是L面?于是需要一个通用的反矩c?/p>

反射矩阵的计是Zq面的,因ؓQQ何反,都需要一个反面?/p>

所以,我们先给出^面表C?Plane(nx,ny,nz,d); 其中(nx,ny,nz)已经单位化?/p>

然后Q我们假讄间中有Q意一点P(x,y,z,1)

设这个点P以Plane为反面的镜像点为P1(x1,y1,z1,w)?/p>

 

Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q?/p>

Ҏ定理Q我们知道, 若两个点以某一点ؓ镜像Q则两个点的坐标之和除以2Q就刚好是中炏V?

q个理论我们用到q里的话Q?那这个中点就刚好是^面上的一个点?q面上的q个点就?P(x,y,z,1) - (nx,ny,nz,0)*D .  其中D是点P到^面的距离

而D=Plane dot P = (x*nx+y*ny+z*nz+d);

׃面的描述Q我们马上想刎ͼ那么要求点P1的话Q就是这?nbsp;

(P+P1)/2 = P(x,y,z,1) - (nx,ny,nz,0)*D

=> P1 = P(x,y,z,1) - 2(nx,ny,nz,0)*D

=>P1 = P(x,y,z,1) - 2(nx,ny,nz,0)*(x*nx+y*ny+z*nz+d)

 

换成矩阵形式则ؓ

                            ?-2*nx*nx   -2*nx*ny         -2*nx*nz         0  |

                             | -2*ny*nx     1 - 2*ny*ny     -2*ny*nz         0  |

P1 = {x,y,z,1}   x   | -2*nz*nx     -2*nz*ny         1-2*nz*nz        0  |

                             | -2*d*nx      -2*d*ny           -2*d*nz           1  |

 

大功告成

btw:q是行主矩阵表示?/p>

Render Donkey 2013-06-15 00:48 发表评论
]]>
h大家一个关于EPOLLET和EPOLLLT的问?/title><link>http://www.shnenglu.com/Leaf/archive/2013/02/25/198061.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Mon, 25 Feb 2013 05:05:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2013/02/25/198061.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/198061.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2013/02/25/198061.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/198061.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/198061.html</trackback:ping><description><![CDATA[今天在查看EPOLLET和EPOLLLT的细节的时候,发现一文章?但不知文中说的是否有道理Q望各位大大l个明确的答复?br />游戏服务器,我们用的是ET方式?br /><a ><br /></a><h2><a ></a><a ><font color="#1086a4">剖析 epoll ET/LT 触发方式的性能差异误解Q定性分析)</font><br /><br /><br /></a><p style="margin: 0px 0px 18px; padding: 0px; color: black; line-height: 18px; font-weight: normal; background-color: #ffffff; font-family: 微Y雅黑; font-size: 16px; "><span style="font-family: Arial; ">qx大家使用 epoll 旉知道其事件触发模式有默认?level-trigger 模式和通过 EPOLLET 启用?edge-trigger 模式两种。从 epoll 发展历史来看Q它刚诞生时只有 edge-trigger 模式Q后来因Ҏ产生 race-cond 且不易被开发者理解,又增加了 level-trigger 模式q作为默认处理方式?/span></p><p style="margin: 0px 0px 18px; padding: 0px; color: black; line-height: 18px; font-weight: normal; background-color: #ffffff; font-family: 微Y雅黑; font-size: 16px; "><span style="font-family: Arial; ">二者的差异在于 level-trigger 模式下只要某?fd 处于 readable/writable 状态,无论什么时候进?epoll_wait 都会q回?fdQ?edge-trigger 模式下只有某?fd ?unreadable 变ؓ readable 或从 unwritable 变ؓ writable Ӟepoll_wait 才会q回?fd?/span></p><p style="margin: 0px 0px 18px; padding: 0px; color: black; line-height: 18px; font-weight: normal; background-color: #ffffff; font-family: 微Y雅黑; font-size: 16px; "><strong style="margin: 0px; padding: 0px; font-family: Arial; ">通常的误区是Qlevel-trigger 模式?epoll 池中存在大量 fd 时效率要显著低于 edge-trigger 模式?/strong></p><p style="margin: 0px 0px 18px; padding: 0px; color: black; line-height: 18px; font-weight: normal; background-color: #ffffff; font-family: 微Y雅黑; font-size: 16px; "><span style="font-family: Arial; ">但从 kernel 代码来看Qedge-trigger/level-trigger 模式的处理逻辑几乎完全相同Q差别仅在于 level-trigger 模式?event 发生时不会将其从 ready list 中移除,略ؓ增大?event 处理q程?kernel space 中记录数据的大小?/span></p><p style="margin: 0px 0px 18px; padding: 0px; color: black; line-height: 18px; font-weight: normal; background-color: #ffffff; font-family: 微Y雅黑; font-size: 16px; "><span style="font-family: Arial; ">然而,edge-trigger 模式一定要配合 user app 中的 ready list l构Q以便收集已出现 event ?fdQ再通过 round-robin 方式挨个处理Q以此避免通信数据量很大时出现忙于处理热点 fd 而导致非热点 fd 饿死的现象。统?kernel ?user spaceQ由?user app ?ready list 的实现千奇百怪,不一定都l过仔细的推敲优化,因此 edge-trigger 的d存开销往往q大?level-trigger 的开销?/span></p><p style="margin: 0px 0px 18px; padding: 0px; color: black; line-height: 18px; font-weight: normal; background-color: #ffffff; font-family: 微Y雅黑; font-size: 16px; "><span style="font-family: Arial; ">一般号U?edge-trigger 模式的优势在于能够减?epoll 相关pȝ调用Q这话不假,?user app 里可不是只有 epoll 相关pȝ调用吧?Zl过饿死问题Qedge-trigger 模式?user app 要自行进?read/write 循环处理Q这其中增加的系l调用和减少?epoll pȝ调用加v来,有谁能说一定就能明昑֜快v来呢Q?/span></p><p style="margin: 0px 0px 18px; padding: 0px; color: black; line-height: 18px; font-weight: normal; background-color: #ffffff; font-family: 微Y雅黑; font-size: 16px; "><span style="font-family: Arial; ">实际上,epoll_wait 的效率是 O(ready fd num) U别的,因此 edge-trigger 模式的真正优势在于减了每次 epoll_wait 可能需要返回的 fd 数量Q在q发 event 数量极多的情况下能加?epoll_wait 的处理速度Q但别忘了这只是针对 epoll 体系自己而言的提升,与此同时 user app 需要增加复杂的逻辑、花Ҏ多的 cpu/mem 与其配合工作QM性能收益I竟如何Q只有实际测量才知道Q无法一概而论。不q,Z降低处理逻辑复杂度,常用的事件处理库大部分都选择?level-trigger 模式Q如 libevent、boost::asio{)</span></p><p style="margin: 0px 0px 18px; padding: 0px; color: black; line-height: 18px; font-weight: normal; background-color: #ffffff; font-family: 微Y雅黑; font-size: 16px; "><strong style="margin: 0px; padding: 0px; font-family: Arial; ">l论Q?br style="margin: 0px; padding: 0px; " />• epoll ?edge-trigger ?level-trigger 模式处理逻辑差异极小Q性能试l果表明常规应用场景 中二者性能差异可以忽略?br style="margin: 0px; padding: 0px; " />• 使用 edge-trigger ?user app 比?level-trigger 的逻辑复杂Q出错概率更高?br style="margin: 0px; padding: 0px; " />• edge-trigger ?level-trigger 的性能差异主要在于 epoll_wait pȝ调用的处理速度Q是否是 user app 的性能瓉需要视应用场景而定Q不可一概而论?/strong></p><p style="margin: 0px 0px 18px; padding: 0px; color: black; line-height: 18px; font-weight: normal; background-color: #ffffff; font-family: 微Y雅黑; font-size: 14px; "><span style="font-family: Arial; ">Ƣ迎此话题q行深入调研、讨论!</span></p><p style="margin: 0px 0px 18px; padding: 0px; color: black; line-height: 18px; font-size: 12px; font-weight: normal; background-color: #ffffff; font-family: 微Y雅黑; "><span style="font-family: Arial; ">参考资料:</span><br style="margin: 0px; padding: 0px; " /><span style="font-family: Arial; ">• linux kernel sourceQfs/eventpoll.c</span><br style="margin: 0px; padding: 0px; " /><span style="font-family: Arial; ">• “Comparing and Evaluating epoll, select, and poll Event</span><br style="margin: 0px; padding: 0px; " /><span style="font-family: Arial; ">Mechanisms”Qhttp://bcr2.uwaterloo.ca/~brecht/papers/getpaper.php?file=ols-2004.pdf</span><br style="margin: 0px; padding: 0px; " /><span style="font-family: Arial; ">• “Edge-triggered interfaces are too difficult?”Qhttp://lwn.net/Articles/25137/</span></p><p style="margin: 0px 0px 18px; padding: 0px; color: #333333; line-height: 18px; font-family: 'Microsoft Yahei', Tahoma, Arial, Helvetica, sans-serif; font-size: 12px; font-weight: normal; background-color: #ffffff; "><span style="font-family: Arial; ">By QingWu</span></p></h2><a ><br /></a><img src ="http://www.shnenglu.com/Leaf/aggbug/198061.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2013-02-25 13:05 <a href="http://www.shnenglu.com/Leaf/archive/2013/02/25/198061.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>代颜色的提示信息输出?/title><link>http://www.shnenglu.com/Leaf/archive/2010/08/20/124041.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Thu, 19 Aug 2010 17:00:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2010/08/20/124041.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/124041.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2010/08/20/124041.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/124041.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/124041.html</trackback:ping><description><![CDATA[前几天在|上搜到一D|变控制台字符颜色的代码,用它做了一个代字体颜色的Log输出。感觉还是比较不错的?br><br>  /*<br>  0 黑色 1 p Q绿 Q浅?br>  Q暗U Q暗紫 Q嫩黄 Q浅?br>  Q浅灰 Q亮蓝 Q0亮绿 Q1非常?br>  Q2大红 Q3亮 Q4黄 Q5白 <br>  */<br><br>q是那段代码。我已做成了ANSI和UNICODE都支持的版本Q具体ؓ什么要q样Q可以看前一关于字W编码与IO的问题?br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> __Printfc(U16 color, </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> TCHAR</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> format,<img src="http://www.shnenglu.com/Images/dot.gif">) <br><img id=Codehighlighter1_54_587_Open_Image onclick="this.style.display='none'; Codehighlighter1_54_587_Open_Text.style.display='none'; Codehighlighter1_54_587_Closed_Image.style.display='inline'; Codehighlighter1_54_587_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_54_587_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_54_587_Closed_Text.style.display='none'; Codehighlighter1_54_587_Open_Image.style.display='inline'; Codehighlighter1_54_587_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>    </span><span id=Codehighlighter1_54_587_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_54_587_Open_Text><span style="COLOR: #000000">{ <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        va_list argList; <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        U16 oldcolor; <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        HANDLE hCon</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">GetStdHandle(STD_OUTPUT_HANDLE); <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        CONSOLE_SCREEN_BUFFER_INFO bInfo; <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        GetConsoleScreenBufferInfo(hCon, </span><span style="COLOR: #000000">&</span><span style="COLOR: #000000">bInfo ); <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        oldcolor </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> bInfo.wAttributes;<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(oldcolor</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">color)<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            SetConsoleTextAttribute(hCon,color); <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>#ifdef _UNICODE<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        _tsetlocale(LC_CTYPE,TEXT(</span><span style="COLOR: #000000">""</span><span style="COLOR: #000000">));<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000"><br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        va_start( argList, format ); <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        _tprintf( format,argList); <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        va_end( argList );<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>#ifdef _UNICODE<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        _tsetlocale(LC_CTYPE,TEXT(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">C</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">));<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000"><br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(oldcolor</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">color)<br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            SetConsoleTextAttribute(hCon,color);  <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>    }</span></span><span style="COLOR: #000000"> <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span></div> <br> <img src ="http://www.shnenglu.com/Leaf/aggbug/124041.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2010-08-20 01:00 <a href="http://www.shnenglu.com/Leaf/archive/2010/08/20/124041.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字符输出与编码集的问题?http://www.shnenglu.com/Leaf/archive/2010/08/19/123908.htmlRender DonkeyRender DonkeyWed, 18 Aug 2010 17:19:00 GMThttp://www.shnenglu.com/Leaf/archive/2010/08/19/123908.htmlhttp://www.shnenglu.com/Leaf/comments/123908.htmlhttp://www.shnenglu.com/Leaf/archive/2010/08/19/123908.html#Feedback0http://www.shnenglu.com/Leaf/comments/commentRss/123908.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/123908.html  晚上回来l箋完善早上的工作,Log输出做成了可以重定向的层ơ结构,q放入了一个可以共享的Share动态库中。这样就可以保持Log输出pȝ的唯一和共享(静态Lib中共无法׃nQ?
      用百度搜了一下这个输出问题,H然发现了其中奥妙,原来Unicode需要本地化信息?br>  l测试发C如下规律
/*
      C?nbsp; CU   非C? 非CU
stdio    1   0    1     1
iostream  1   1    0     0


可以得出
Q、在多字节时Q默?CQ风gQ二者都能输Z文?br>Q、在多字节时Q非C风格下,cout不能输出中文
Q、在UӞ默认C风格下,print不能输出中文
Q、在UӞ非C风格下,cout不能输出中文


由此可知Q要在C风格下,iostream才能输出中文?br>而printf只有在C风格的Unicode下才不能输出中文Q其它均可?/font>
*/

试代码如下
#include <iostream>
#include <tchar.h>
#include <locale>
int _tmain(int argc, _TCHAR* argv[])
{
#ifdef _UNICODE
 _tsetlocale(LC_CTYPE,TEXT(""));
#endif
 _tprintf(TEXT("a在哪里啊\n"));
#ifdef _UNICODE
 _tsetlocale(LC_CTYPE,TEXT("C"));
#endif


#ifdef _UNICODE
 std::wcout<<"d在哪里啊"<<std::endl;
#else
 std::cout<<"d在哪里啊"<<std::endl;
#endif
 getchar();
 return 0;
}


Render Donkey 2010-08-19 01:19 发表评论
]]>
发几个自己做的东?/title><link>http://www.shnenglu.com/Leaf/archive/2010/06/20/118321.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Sun, 20 Jun 2010 14:04:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2010/06/20/118321.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/118321.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2010/06/20/118321.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/118321.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/118321.html</trackback:ping><description><![CDATA[     摘要: 最大的遗憾莫过于大学里没做q啥像样的东西,许多东西都烂在了学校那破盘里,p点了Q有需要的可以下蝲?<br>代码写得很烂Q不是hȝ。不q能~译通,能执行?<br> <br>其中三维模型导入是用OPENGL+GLUT+VS 2005 <br>墙中公主?D贪食蛇是用的D3DAPI+VC6.0  <a href='http://www.shnenglu.com/Leaf/archive/2010/06/20/118321.html'>阅读全文</a><img src ="http://www.shnenglu.com/Leaf/aggbug/118321.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2010-06-20 22:04 <a href="http://www.shnenglu.com/Leaf/archive/2010/06/20/118321.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>收录QVC调试技?/title><link>http://www.shnenglu.com/Leaf/archive/2010/05/24/116244.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Mon, 24 May 2010 11:54:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2010/05/24/116244.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/116244.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2010/05/24/116244.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/116244.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/116244.html</trackback:ping><description><![CDATA[     摘要: 调试是一个程序员最基本的技能,光要性甚臌q学习一门语a。不会调试的E序员就意味着他即使会一门语aQ却不能~制ZQ何好的Y件?<br> <br>q里我简要的Ҏ自己的经验列试中比较常用的技巧,希望对大家有用?nbsp; <a href='http://www.shnenglu.com/Leaf/archive/2010/05/24/116244.html'>阅读全文</a><img src ="http://www.shnenglu.com/Leaf/aggbug/116244.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2010-05-24 19:54 <a href="http://www.shnenglu.com/Leaf/archive/2010/05/24/116244.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>发几道关于C++基础知识的题Q能不能做自己清楚就行?/title><link>http://www.shnenglu.com/Leaf/archive/2010/05/11/115067.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Tue, 11 May 2010 00:52:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2010/05/11/115067.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/115067.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2010/05/11/115067.html#Feedback</comments><slash:comments>31</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/115067.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/115067.html</trackback:ping><description><![CDATA[     摘要: 下面q些是基题,“高手”们飘过Q!Q?<br>我想一般公司对语言斚wQM变着Ҏ考下面的q些问题。这只是出现的一UŞ式。有啥好题欢q大家分享,下面q些是我自己YY的。看题的兄弟只需在自己心里作{就行,一定不要忘了几乎每题都有一个?Z么”?<br>  <a href='http://www.shnenglu.com/Leaf/archive/2010/05/11/115067.html'>阅读全文</a><img src ="http://www.shnenglu.com/Leaf/aggbug/115067.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2010-05-11 08:52 <a href="http://www.shnenglu.com/Leaf/archive/2010/05/11/115067.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>讨论会结?/title><link>http://www.shnenglu.com/Leaf/archive/2010/05/09/114942.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Sun, 09 May 2010 11:38:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2010/05/09/114942.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/114942.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2010/05/09/114942.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/114942.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/114942.html</trackback:ping><description><![CDATA[     摘要: 前几天发了一关于一个缓冲区溢出问题的讨论。当然是饱受非意。有q是撞大q,有h说这是无聊。但是呢Q从讨论中,我们发现了更多的问题。学C更多的知识?其实许多时候我们有必要“撞大运”,但是在撞大运出问题之后,一定要弄清楚事情的原因?博友的回复已l充分说明了当时的问题?但是提出了一个新问题Q就是时变量分配时的空间问题?<br>比如说有分连l分配了3个时变量,却发现这3个时变量的址址不是按变量大连l。(如两个INT变量间相差是12Q而非预期?Q?又或者后声明的变量地址却跑在了前头Q? <br>  <a href='http://www.shnenglu.com/Leaf/archive/2010/05/09/114942.html'>阅读全文</a><img src ="http://www.shnenglu.com/Leaf/aggbug/114942.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2010-05-09 19:38 <a href="http://www.shnenglu.com/Leaf/archive/2010/05/09/114942.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>讨论会:一个不是问题的问题!http://www.shnenglu.com/Leaf/archive/2010/05/06/114596.htmlRender DonkeyRender DonkeyThu, 06 May 2010 04:41:00 GMThttp://www.shnenglu.com/Leaf/archive/2010/05/06/114596.htmlhttp://www.shnenglu.com/Leaf/comments/114596.htmlhttp://www.shnenglu.com/Leaf/archive/2010/05/06/114596.html#Feedback38http://www.shnenglu.com/Leaf/comments/commentRss/114596.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/114596.html

不知道各位有何高见!
我心中也有一个答案。但先不_大家一h讨论。。?共同完成q篇贴子?随后Q大家的高端回复会以如下方式出现
如果不希望最后出现在q里Q请大家注明?默认情况下,表示同意Q?

IDQXXXX
解释Q?****************


=======================
IDQXXXXX
解释Q?*******************  阅读全文

Render Donkey 2010-05-06 12:41 发表评论
]]>
[原]深入讲解函数中分配内存问?/title><link>http://www.shnenglu.com/Leaf/archive/2010/05/05/114425.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Wed, 05 May 2010 01:02:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2010/05/05/114425.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/114425.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2010/05/05/114425.html#Feedback</comments><slash:comments>13</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/114425.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/114425.html</trackback:ping><description><![CDATA[     摘要: 开始写了一,通过说明他们产生了拷贝,而导致p不能成功分配。但q未提出事实ҎQ下面我们来仔细看看具体原因?<br> <br>我们需要弄清两点:1、main函数中的p与MyNew函数中的p是不是一P2、如果不一P是怎么D了不一L?<br>  <a href='http://www.shnenglu.com/Leaf/archive/2010/05/05/114425.html'>阅读全文</a><img src ="http://www.shnenglu.com/Leaf/aggbug/114425.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2010-05-05 09:02 <a href="http://www.shnenglu.com/Leaf/archive/2010/05/05/114425.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>冒排序与选择排序的不同、快速排序与选择排序的结?/title><link>http://www.shnenglu.com/Leaf/archive/2010/05/04/114393.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Tue, 04 May 2010 15:44:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2010/05/04/114393.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/114393.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2010/05/04/114393.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/114393.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/114393.html</trackback:ping><description><![CDATA[     摘要: 目前qؓ使用的快速排序和选择排序联合使用Q也会有意想不到的提升! <br>众所周知Q当用快速排序法排序Ӟ划分到很l的时候,明显很亏?比如Q两三个数排序却要划分成两堆Q这样很划不来。所以,我们可以讑֮一个阀|当快速排序划分到一定粒度的时候,侉K用选择排序?至于q个阀|可以通过performace来测试,以得C个“最优值?<br> <br>  <a href='http://www.shnenglu.com/Leaf/archive/2010/05/04/114393.html'>阅读全文</a><img src ="http://www.shnenglu.com/Leaf/aggbug/114393.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2010-05-04 23:44 <a href="http://www.shnenglu.com/Leaf/archive/2010/05/04/114393.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>某内存池中的指针用法 http://www.shnenglu.com/Leaf/archive/2010/05/03/114263.htmlRender DonkeyRender DonkeyMon, 03 May 2010 10:33:00 GMThttp://www.shnenglu.com/Leaf/archive/2010/05/03/114263.htmlhttp://www.shnenglu.com/Leaf/comments/114263.htmlhttp://www.shnenglu.com/Leaf/archive/2010/05/03/114263.html#Feedback11http://www.shnenglu.com/Leaf/comments/commentRss/114263.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/114263.html内存池实现有许多U,各有不同的优~点?/p>

q里不是主要说内存池Q只是觉得这个内存池中的指针用得很飘逸!

 

 1template <class T,int AllocSize = 50>   
 2class MemPool   
 3{   
 4public:   
 5    static void* operator new(size_t allocLength)   
 6    {   
 7        if(!mStartPotinter)   
 8        {   
 9            MyAlloc();   
10        }
   
11        //当前指向空闲内存v始地址作ؓ反回地址   
12        unsigned char* p = mStartPotinter;   
13        //取出I闲区域?字节的|赋值给I闲地址   
14        //因ؓ前四字节中存放了下一个BLOCK的地址   
15        mStartPotinter = *(unsigned char**)mStartPotinter;   
16        return p;   
17    }
   
18  
19    static void operator delete(void* deleteP)   
20    {   
21//      assert(deletePointer);   
22        *(unsigned char**)deleteP = mStartPotinter;   
23        mStartPotinter = (unsigned char*)deleteP;   
24    }
   
25  
26    static void MyAlloc()   
27    {   
28        //预分配内?nbsp;  
29        mStartPotinter = new unsigned char[sizeof(T)*AllocSize];   
30        //构造BLOCK之间的关p?nbsp;   
31        //每个BLOCK的前4BYTE存放了下一个BLOCK的地址   
32        unsigned char** next = (unsigned char**)mStartPotinter;   
33        unsigned char* p = mStartPotinter;   
34  
35        for(int i = 0; i< AllocSize;++i)   
36        {   
37            p +=sizeof(T);//步进   
38            *next = p;//赋?nbsp;  
39            next = (unsigned char**)p;//步进   
40        }
   
41        *next = NULL;   
42    }
   
43  
44    static unsigned char* mStartPotinter;   
45}
;   
46  
47template <class T,int AllocSize>   
48unsigned char* MemPool<T,AllocSize>::mStartPotinter = NULL;  
49
50
51本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/wqjqepr/archive/2010/05/03/5552322.aspx

 

 

单提CZ下: unsigned char** next = (unsigned char**)mStartPotinter;

mStartPotinter作ؓ二维指针的时候,相当于是一pd的unsigned char* [].

对于W一?*next 相当?unsigned char*)mStartPointer[0].

W二个相当于(unsigned char*)mStartPointer[sizeof(T)*1];

W三个相当于(unsigned char*)mStartPointer[sizeof(T)*2];

所以,构造BLOCK之间关系的时候,也可以写?/p>

 

1for(int i = 0; i< AllocSize;++i)   
2{   
3 p +=sizeof(T);//步进   
4 unsigned char* pp = (unsigned char*)(p[sizeof(T)*i]);   
5 pp = p;//赋?nbsp;  
6}
 

 

 

不想多解释了Q篏。估计多看几分种啥都明白了!

 

 



Render Donkey 2010-05-03 18:33 发表评论
]]>
[转]C++ 对象的内存布局http://www.shnenglu.com/Leaf/archive/2010/04/27/113740.htmlRender DonkeyRender DonkeyTue, 27 Apr 2010 12:56:00 GMThttp://www.shnenglu.com/Leaf/archive/2010/04/27/113740.htmlhttp://www.shnenglu.com/Leaf/comments/113740.htmlhttp://www.shnenglu.com/Leaf/archive/2010/04/27/113740.html#Feedback5http://www.shnenglu.com/Leaf/comments/commentRss/113740.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/113740.html讲述了C++对象在以下情늚内存布局。值得一看!
1Q有成员变量的情c?

2Q有重复l承的情c?

3Q有虚拟l承的情c?

4Q有ȝ型虚拟承的情况?

q有Q对于前几天的脓子表C报歉,今天是直接脓到这里的?没ؕ码,q好Q!Q?nbsp; 阅读全文

Render Donkey 2010-04-27 20:56 发表评论
]]>
c++虚函数表探究http://www.shnenglu.com/Leaf/archive/2009/07/24/91095.htmlRender DonkeyRender DonkeyFri, 24 Jul 2009 15:52:00 GMThttp://www.shnenglu.com/Leaf/archive/2009/07/24/91095.htmlhttp://www.shnenglu.com/Leaf/comments/91095.htmlhttp://www.shnenglu.com/Leaf/archive/2009/07/24/91095.html#Feedback0http://www.shnenglu.com/Leaf/comments/commentRss/91095.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/91095.htmlC++中的虚函数的作用主要是实C多态的机制。关于多态,而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子cȝ成员函数。这U技术可以让父类的指针有“多种形?#8221;Q这是一U泛型技术。所谓泛型技术,说白了就是试图用不变的代码来实现可变的法。比如:模板技术,RTTI技术,虚函数技术,要么是试囑ց到在~译时决议,要么试图做到q行时决议?
关于虚函数的使用ҎQ我在这里不做过多的阐述。大家可以看看相关的C++的书c。在q篇文章中,我只想从虚函数的实现机制上面为大?一个清晰的剖析?
当然Q相同的文章在网上也出现q一些了Q但我L觉这些文章不是很Ҏ阅读Q大D大D늚代码Q没有图片,没有详细的说明,没有比较Q没有D一反三。不利于学习和阅读,所以这是我惛_下这文章的原因。也希望大家多给我提意见?
a归正传,让我们一赯入虚函数的世界?
虚函数表
对C++ 了解的h都应该知道虚函数QVirtual FunctionQ是通过一张虚函数表(Virtual TableQ来实现的。简UCؓV-Table?在这个表中,L要一个类的虚函数的地址表,q张表解决了l承、覆盖的问题Q保证其容真实反应实际的函数。这P在有虚函数的cȝ实例中这个表被分配在?q个实例的内存中Q所以,当我们用父类的指针来操作一个子cȝ时候,q张虚函数表显得由为重要了Q它像一个地图一P指明了实际所应该调用的函数?
q里我们着重看一下这张虚函数表。在C++的标准规D明书中说刎ͼ~译器必需要保证虚函数表的指针存在于对象实例中最前面的位|(q是Z保证正确取到虚函数的偏移量)?q意味着我们通过对象实例的地址得到q张虚函数表Q然后就可以遍历其中函数指针Qƈ调用相应的函数?
听我扯了那么多,我可以感觉出来你现在可能比以前更加晕头{向了?没关p,下面是实际的例子,怿聪明的你一看就明白了?
假设我们有这L一个类Q?
class Base {
public:
virtual void f() { cout << "Base::f" << endl; }
virtual void g() { cout << "Base::g" << endl; }
virtual void h() { cout << "Base::h" << endl; }
};
按照上面的说法,我们可以通过Base的实例来得到虚函数表?下面是实际例E:
typedef void(*Fun)(void);
Base b;
Fun pFun = NULL;
cout << "虚函数表地址Q? << (int*)(&b) << endl;
cout << "虚函数表 ?W一个函数地址Q? << (int*)*(int*)(&b) << endl;
// Invoke the first virtual function
pFun = (Fun)*((int*)*(int*)(&b));
pFun();
实际q行l果如下Q?Windows XP+VS2003, Linux 2.6.22 + GCC 4.1.3)
虚函数表地址Q?012FED4
虚函数表 ?W一个函数地址Q?044F148
Base::f
通过q个CZQ我们可以看刎ͼ我们可以通过?amp;b转成int *Q取得虚函数表的地址Q然后,再次取址可以得到第一个虚函数的地址了,也就是Base::f()Q这在上面的E序中得C验证Q把int* 强制转成了函数指针)。通过q个CZQ我们就可以知道如果要调用Base::g()和Base::h()Q其代码如下Q?
(Fun)*((int*)*(int*)(&b)+0); // Base::f()
(Fun)*((int*)*(int*)(&b)+1); // Base::g()
(Fun)*((int*)*(int*)(&b)+2); // Base::h()
q个时候你应该懂了吧。什么?q是有点晕。也是,q样的代码看着太ؕ了。没问题Q让我画个图解释一下。如下所C:


注意Q在上面q个图中Q我在虚函数表的最后多加了一个结点,q是虚函数表的结束结点,像字符串的l束W?#8220;\0”一P其标志了虚函数表的结束。这个结束标志的值在不同的编译器下是不同的。在WinXP+VS2003下,q个值是NULL。而在Ubuntu 7.10 + Linux 2.6.22 + GCC 4.1.3下,q个值是如果1Q表C有下一个虚函数表,如果值是0Q表C是最后一个虚函数表?
下面Q我分别说?#8220;无覆?#8221;?#8220;有覆?#8221;时的虚函数表的样子。没有覆盖父cȝ虚函数是毫无意义的。我之所以要讲述没有覆盖的情况,主要目的是ؓ了给一个对比。在比较之下Q我们可以更加清楚地知道其内部的具体实现?
一般承(无虚函数覆盖Q?br>下面Q再让我们来看看l承时的虚函数表是什么样的。假设有如下所C的一个承关p:
 

h意,在这个承关pMQ子cL有重载Q何父cȝ函数。那么,在派生类的实例中Q其虚函数表如下所C:
对于实例QDerive d; 的虚函数表如下:

 

 

我们可以看到下面几点Q?
1Q虚函数按照其声明顺序放于表中?
2Q父cȝ虚函数在子类的虚函数前面?
我相信聪明的你一定可以参考前面的那个E序Q来~写一D늨序来验证?
一般承(有虚函数覆盖Q?br>覆盖父类的虚函数是很昄的事情,不然Q虚函数变得毫无意义。下面,我们来看一下,如果子类中有虚函数重载了父类的虚函数Q会是一个什么样子?假设Q我们有下面q样的一个承关pR?

Z让大家看到被l承q后的效果,在这个类的设计中Q我只覆盖了父类的一个函敎ͼf()。那么,对于zcȝ实例Q其虚函数表会是下面的一个样子:
 

我们从表中可以看C面几点,
1Q覆盖的f()函数被放C虚表中原来父c虚函数的位|?
2Q没有被覆盖的函C旧?
q样Q我们就可以看到对于下面q样的程序,
Base *b = new Derive();
b->f();
由b所指的内存中的虚函数表的f()的位|已l被Derive::f()函数地址所取代Q于是在实际调用发生Ӟ是Derive::f()被调用了。这实C多态?
多重l承Q无虚函数覆盖)
下面Q再让我们来看看多重l承中的情况Q假设有下面q样一个类的承关pR注意:子类q没有覆盖父cȝ函数?


对于子类实例中的虚函数表Q是下面q个样子Q?

 


我们可以看到Q?
1Q?每个父类都有自己的虚表?
2Q?子类的成员函数被攑ֈ了第一个父cȝ表中。(所谓的W一个父cL按照声明序来判断的Q?
q样做就是ؓ了解决不同的父类cd的指针指向同一个子cd例,而能够调用到实际的函数?
多重l承Q有虚函数覆盖)
下面我们再来看看Q如果发生虚函数覆盖的情c?
下图中,我们在子cM覆盖了父cȝf()函数?

下面是对于子cd例中的虚函数表的图:
 

我们可以看见Q三个父c虚函数表中的f()的位|被替换成了子类的函数指针。这P我们可以Q一静态类型的父类来指向子c,q调用子cȝf()了。如Q?
Derive d;
Base1 *b1 = &d;
Base2 *b2 = &d;
Base3 *b3 = &d;
b1->f(); //Derive::f()
b2->f(); //Derive::f()
b3->f(); //Derive::f()
b1->g(); //Base1::g()
b2->g(); //Base2::g()
b3->g(); //Base3::g()
安全?br>每次写C++的文章,d不了要批判一下C++。这文章也不例外。通过上面的讲qͼ怿我们对虚函数表有一个比较细致的了解了。水可蝲舟,亦可覆舟。下面,让我们来看看我们可以用虚函数表来q点什么坏事吧?
一、通过父类型的指针讉K子类自己的虚函数
我们知道Q子cL有重载父cȝ虚函数是一件毫无意义的事情。因为多态也是要Z函数重蝲的。虽然在上面的图中我们可以看到Base1的虚表中有Derive的虚函数Q但我们Ҏ不可能用下面的语句来调用子cȝ自有虚函敎ͼ
Base1 *b1 = new Derive();
b1->f1(); //~译出错
M妄图使用父类指针惌用子cM的未覆盖父类的成员函数的行ؓ都会被编译器视ؓ非法Q所以,q样的程序根本无法编译通过。但在运行时Q我们可以通过指针的方式访问虚函数表来辑ֈq反C++语义的行为。(关于q方面的试Q通过阅读后面附录的代码,怿你可以做到这一点)
二、访问non-public的虚函数
另外Q如果父cȝ虚函数是private或是protected的,但这些非public的虚函数同样会存在于虚函数表中,所以,我们同样可以使用讉K虚函数表的方式来讉Kq些non-public的虚函数Q这是很Ҏ做到的?
如:
class Base {
private:
virtual void f() { cout << "Base::f" << endl; }
};
class Derive : public Base{
};
typedef void(*Fun)(void);
void main() {
Derive d;
Fun pFun = (Fun)*((int*)*(int*)(&d)+0);
pFun();
}



Render Donkey 2009-07-24 23:52 发表评论
]]>
[转] extern "C"http://www.shnenglu.com/Leaf/archive/2009/05/17/83229.htmlRender DonkeyRender DonkeySun, 17 May 2009 15:46:00 GMThttp://www.shnenglu.com/Leaf/archive/2009/05/17/83229.htmlhttp://www.shnenglu.com/Leaf/comments/83229.htmlhttp://www.shnenglu.com/Leaf/archive/2009/05/17/83229.html#Feedback0http://www.shnenglu.com/Leaf/comments/commentRss/83229.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/83229.html

前些天,~程序是用到了很久以前写的CE序Q想把里面的函数利用hQ连接发现出C找不到具体函数的错误Q?/p>

以下是假设旧的CE序?/p>

C的头文g

/*-----------c.h--------------*/
#ifndef _C_H_
#define _C_H_
extern int add(int x, int y);
#endif

C的源文g

/*-----------c.c--------------*/
int
add(int x, int y){
return
x+y;
}

C++的调?/p>

/*-----------cpp.cpp--------------*/
#include "c.h"
void main()
{

add(1, 0);
}

q样~译会生错误cpp.obj : error LNK2001: unresolved external symbol "int __cdecl add(int,int)" (?add@@YAHHH@Z)Q原因是找不到add的目标模?/p>

q才令我惌vC++重蝲的函数命名方式和C函数的命名方式,让我们回一下:C中函数编译后命名会在函数名前加以"_",比如add函数~译成obj文g时的实际命名为_addQ而c++命名则不同,Z实现函数重蝲同样的函数名add因参数的不同会被~译成不同的名字

例如

int add(int , int)==>add@@YAHHH@Z,

float add(float , float )==>add@@YAMMM@Z,

以上是VC6的命名方式,不同的编译器会不同,M不同的参数同L函数名将~译成不同目标名Q以便于函数重蝲是调用具体的函数?/p>

~译cpp.cpp中编译器在cpp文g中发现add(1, 0);的调用而函数声明ؓextern int add(int x, int y);~译器就军_Ladd@@YAHHH@ZQ可惜他找不刎ͼ因ؓC的源文g?font color=#990000>extern int add(int x, int y);~译成_add了;

Z解决q个问题C++采用了extern "C",q就是我们的主题Q想要利用以前的CE序库,那么你就要学会它Q我们可以看以下标准头文件你会发玎ͼ很多头文仉有以下的l构

#ifndef __H
#define __H
#ifdef __cplusplus
extern "C" {
#endif

extern
int f1(int, int);
extern
int f2(int, int);
extern
int f3(int, int);


#ifdef __cplusplus
}
#endif

#endif /*__H*/

如果我们仿制该头文g可以得到

#ifndef _C_H_
#define _C_H_
#ifdef __cplusplus
extern "C" {
#endif

extern
int add(int, int);

#ifdef __cplusplus
}
#endif

#endif /* _C_H_ */

q样~译

/*-----------c.c--------------*/
int
add(int x, int y){
return
x+y;
}

q时源文件ؓ*.cQ?/font>__cplusplus没有被定义,extern "C" {}q时没有生效对于C他看到只?font color=#990000>extern int add(int, int);
add函数~译成_add(int, int);

而编译c++源文?/font>

/*-----------cpp.cpp--------------*/
#include "c.h"
void main()
{

add(1, 0);
}

q时源文件ؓ*.cpp,__cplusplus被定?对于C++他看到的?font color=#990000>extern "C" {extern int add(int, int);}~译器就会知?add(1, 0);调用的C风格的函敎ͼ׃知道去c.obj中找_add(int, int)而不?/strong>add@@YAHHH@ZQ?/font>

q也׃ؓ什么DLL中常看见extern "C" {}Q?/strong>windows是采用C语言~制他首先要考虑到C可以正确调用q些DLLQ而用户可能会使用C++?font color=#990000>extern "C" {}׃发生作用

Render Donkey 2009-05-17 23:46 发表评论
]]>[转]C++中宏的?/title><link>http://www.shnenglu.com/Leaf/archive/2009/05/17/83228.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Sun, 17 May 2009 15:41:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2009/05/17/83228.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/83228.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2009/05/17/83228.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/83228.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/83228.html</trackback:ping><description><![CDATA[<div id="35jl5d1" class=postbody>关于## ?#?@的用?br><br><br><span style="COLOR: red">##</span> 是连接符?q接两个?##被称接符QconcatenatorQ,用来两个Tokenq接Z个Token。注意这里连接的对象是TokenpQ而不一定是宏的?<br>量。比如你要做一个菜单项命o名和函数指针l成的结构体的数l,q且希望在函数名和菜单项命o名之间有直观的、名字上的关pR那可以用:宏参?# <br>固定部分。当然还可以n?#W号q接 n+1个TokenQ这个特性也?W号所不具备的?<br>#define LINK_MULTIPLE(a,b,c,d) a##_##b##_##c##_##d<br>typedef struct _record_type LINK_MULTIPLE(name,company,position,salary);<br>// q里q个语句展开为:<br>//      typedef struct _record_type name_company_position_salary;<br><br><br><span style="COLOR: red">#@</span>       功能是将其后面的宏参数进行字W化?br><br>#define makechar(x)  <a href="mailto:#@xa"><font color=#005880>#@x<br>a</font></a> = makechar(b);<br>//a = 'b';<br><br><br><span style="COLOR: red">#</span>   是把名字代替成字W串,宏体中,#的功能是其后面的宏参数q行字符串化操作QStringficationQ,单说是在对它所引用的宏变量通过替换后在其左叛_加上一?<br>双引受?br>#define WARN_IF(EXP)        \<br>        do{ if (EXP)        \<br>                fprintf(stderr, "Warning: " #EXP "\n"); }       \<br>        while(0)<br>那么实际使用中会出现下面所C的替换q程Q?<br>WARN_IF (divider == 0);<br>被替换ؓ<br>do {<br>        if (divider == 0)<br>fprintf(stderr, "Warning" "divider == 0" "\n");<br>} while(0);<br>q样每次dividerQ除敎ͼ?的时候便会在标准错误上输出一个提CZ息?<br><br><br><span style="COLOR: red"> <dt><strong>!IF </strong><span id="dvxl5jh" class=parameter>constantexpression</span> <dd> <p>如果 <span id="pbnf35h" class=parameter>constantexpression</span> 计算l果为非零|则处?<strong>!IF</strong> 和下一?<strong>!ELSE</strong> ?<strong>!ENDIF</strong> 之间的语句?br><strong>!ENDIF</strong> </p> </dd><span style="COLOR: red"><span style="COLOR: red"><font style="FONT-SIZE: 12pt" face=#ce_temp_font#> <dd> <p>标记 <strong>!IF</strong>?strong>!IFDEF</strong> ?<strong>!IFNDEF</strong> 块的l尾。同一行上 <strong>!ENDIF</strong> 后面的所有文本被忽略?/p> </font></dd></span> <dd></dd></span> <dd></dd></span> <dd></dd></div> <script type=text/javascript> //<![cdata[ Sys.WebForms.PageRequestManager._initialize('AjaxHolder$scriptmanager1', document.getElementById('Form1')); Sys.WebForms.PageRequestManager.getInstance()._updateControls(['tAjaxHolder$UpdatePanel1'], [], [], 90); //]]> </script> <img src ="http://www.shnenglu.com/Leaf/aggbug/83228.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2009-05-17 23:41 <a href="http://www.shnenglu.com/Leaf/archive/2009/05/17/83228.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]通过例子学习Luahttp://www.shnenglu.com/Leaf/archive/2009/05/16/83145.htmlRender DonkeyRender DonkeySat, 16 May 2009 13:37:00 GMThttp://www.shnenglu.com/Leaf/archive/2009/05/16/83145.htmlhttp://www.shnenglu.com/Leaf/comments/83145.htmlhttp://www.shnenglu.com/Leaf/archive/2009/05/16/83145.html#Feedback0http://www.shnenglu.com/Leaf/comments/commentRss/83145.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/83145.html据说本文作者是OGDEV的HACK达h

通过例子学习Lua(1) ---- Hello World

1.前言
游戏中少不了用到脚本语言. Lua是一U和C/C++l合非常紧密的脚本语aQ效率极高?br>一般是Ҏ间要求比较高的地方用C++写,而经帔R要改动的地方用Lua写?/p>

偶最q在学习Lua, 所以写出心得和大家׃n. Lua是一U完全免费的脚本语言,
它的官方|站?a >http://www.lua.org.在网站上可以下蝲到lua的源? 没有?br>执行版本, 不过不用担心, 因ؓlua源码可以在Q何一UC/C++的编译器上编?

如果要学习Lua, 官方|站上的Reference是必备的Q上面有每个命o的用法,非常?br>l?br>参考手?http://www.lua.org/manual/5.0/
作者写的Programming in Lua http://www.lua.org/pil/

2.~译
如果用的VC, 可以下蝲所需的project文g,地址?br>http://sourceforge.net/project/showfiles.php?group_id=32250&package_id=115604
偶用的是cygwin和linux, 打入以下命o卛_,
tar -zxvf lua-5.0.2.tar.gz
cd lua-5.0.2
sh ./configure
make
q样OK了?br>Z以后使用方便Q最好把bin目录加入到path里面?/p>

3."Hello, world!"
现在开始偶们的W一个小E序"Hello, world!"
把以下程序打入文件e01.lua

?:e01.lua
-- Hello World in Lua
print("Hello World.")

Lua有两U执行方式,一U是嵌入到CE序中执行,q有一U是直接从命令行方式下执
行?br>q里Z调试方便Q采用第二种方式Q执行命?lua e01.lua

输出l果应该是:
Hello World.

4.E序说明
W一?-- Hello World in Lua
q句是注释,其中--和C++中的//意思是一L
W二?print("Hello World.")
调用lua内部命oprintQ输?Hello World."字符串到屏幕QLua中的字符串全部是
?括v来的?br>q个命o是一个函数的调用Qprint是lua的一个函敎ͼ?Hello World."是print的参
数?/p>

5.试试?br>在Lua中有不少字符串的处理操作Q本ơ的译֐试试看的内容是Q找接两个字W串
的操作,
q且print出来?br>--

通过例子学习Lua(2) --- Lua基础

1. 函数的?br>以下E序演示了如何在Lua中用函? 及局部变?br>例e02.lua
-- functions
function pythagorean(a, b)   
       local c2 = a^2 + b^2   
       return sqrt(c2)
end
print(pythagorean(3,4))

q行l果
5

E序说明
在Lua中函数的定义格式?
function 函数?参数)
       ...
end
与Pascal语言不同, end不需要与begin配对, 只需要在函数l束后打个end可以了.
本例函数的作用是已知直角三角形直角边, 求斜辚w? 参数a,b分别表示直角辚w,
在函数内定义了local形变量用于存储斜边的qx. 与C语言相同, 定义在函数内的代
码不会被直接执行, 只有ȝ序调用时才会被执?
local表示定义一个局部变? 如果不加local刚表Cc2Z个全局变量, local的作用域
是在最里层的end和其配对的关键字之间, 如if ... end, while ... end{。全局变量
?br>作用域是整个E序?/p>

2. 循环语句
例e03.lua
-- Loops
for i=1,5 do   
       print("i is now " .. i)
end

q行l果
i is now 1
i is now 2
i is now 3
i is now 4
i is now 5

E序说明
q里偶们用到了for语句
for 变量 = 参数1, 参数2, 参数3 do
       循环?br>end
变量以参数3为步? 由参?变化到参?
例如:   
for i=1,f(x) do print(i) end
for i=10,1,-1 do print(i) end

q里print("i is now " .. i)中,偶们用到?.Q这是用来连接两个字W串的,
偶在(1)的试试看中提到的Q不知道你们{对了没有?br>虽然q里i是一个整型量QLua在处理的时候会自动转成字符串型Q不需偶们费心?/p>

3. 条g分支语句
例e04.lua
-- Loops and conditionals
for i=1,5 do
       print(“i is now “ .. i)
         if i < 2 then       
               print(“small”)   
         elseif i < 4 then       
               print(“medium”)   
         else       
               print(“big”)   
         end
end

q行l果
i is now 1
small
i is now 2
medium
i is now 3
medium
i is now 4
big
i is now 5
big

E序说明
if else用法比较? cM于C语言, 不过此处需要注意的是整个if只需要一个end,
哪怕用了多个elseif, 也是一个end.
例如
    if op == "+" then
      r = a + b
    elseif op == "-" then
      r = a - b
    elseif op == "*" then
      r = a*b
    elseif op == "/" then
      r = a/b
    else
      error("invalid operation")
    end


4.试试?br>Lua中除了for循环以外, q支持多U@? Lwhile...do和repeat...until改写本文
中的forE序

--
通过例子学习Lua(3) ---- 数据l构

1.?
Lua语言只有一U基本数据结? 那就是table, 所有其他数据结构如数组?
cd, 都可以由table实现.

2.table的下?
例e05.lua
-- Arrays
myData = {}
myData[0] = “foo”
myData[1] = 42

-- Hash tables
myData[“bar”] = “baz”

-- Iterate through the
-- structure
for key, value in myData do
print(key .. “=“ .. value)
end

输出l果
0=foo
1=42
bar=baz

E序说明
首先定义了一个table myData={}, 然后用数字作Z标赋了两个值给? q种
定义ҎcM于C中的数组, 但与数组不同的是, 每个数组元素不需要ؓ相同cd,
像本例中一个ؓ整型, 一个ؓ字符?

E序W二部分, 以字W串做ؓ下标, 又向table内增加了一个元? q种table非常
像STL里面的map. table下标可以为Lua所支持的Q意基本类? 除了nilg?

Lua对Table占用内存的处理是自动? 如下面这D代?
a = {}
a["x"] = 10
b = a -- `b' refers to the same table as `a'
print(b["x"]) --> 10
b["x"] = 20
print(a["x"]) --> 20
a = nil -- now only `b' still refers to the table
b = nil -- now there are no references left to the table
b和a都指向相同的table, 只占用一块内? 当执行到a = nil? b仍然指向table,
而当执行到b=nil? 因ؓ没有指向table的变量了, 所以Lua会自动释放table所占内?

3.Table的嵌?
Table的用还可以嵌套Q如下例
例e06.lua
-- Table ‘constructor’
myPolygon = {
color=“blue”,
thickness=2,
npoints=4;
{x=0, y=0},
{x=-10, y=0},
{x=-5, y=4},
{x=0, y=4}
}

-- Print the color
print(myPolygon[“color”])

-- Print it again using dot
-- notation
print(myPolygon.color)

-- The points are accessible
-- in myPolygon[1] to myPolygon[4]

-- Print the second point’s x
-- coordinate
print(myPolygon[2].x)

E序说明
首先建立一个table, 与上一例不同的是,在table的constructor里面有{x=0,y=0},
q是什么意思呢Q?q其实就是一个小table, 定义在了大table之内, table?
table名省略了.
最后一行myPolygon[2].xQ就是大table里面table的访问方?

--
通过例子学习Lua(4) -- 函数的调?

1.不定参数
例e07.lua
-- Functions can take a
-- variable number of
-- arguments.
function funky_print (...)
for i=1, arg.n do
print("FuNkY: " .. arg)
end
end

funky_print("one", "two")

q行l果
FuNkY: one
FuNkY: two

E序说明
* 如果?..为参? 则表C参数的数量不定.
* 参数会自动存储C个叫arg的table?
* arg.n中存攑֏数的个数. arg[]加下标就可以遍历所有的参数.


2.以table做ؓ参数
例e08.lua
-- Functions with table
-- parameters
function print_contents(t)
for k,v in t do
print(k .. "=" .. v)
end
end
print_contents{x=10, y=20}

q行l果
x=10
y=20

E序说明
* print_contents{x=10, y=20}q句参数没加圆括? 因ؓ以单个table为参数的时?
不需要加圆括?
* for k,v in t do q个语句是对table中的所有值遍? k中存攑֐U? v中存攑ր?


3.把Lua变成cMXML的数据描q语a
例e09.lua
function contact(t)
-- add the contact ‘t’, which is
-- stored as a table, to a database
end

contact {
name = "Game Developer",
email = "hack@ogdev.net",
url = "http://www.ogdev.net,
quote = [[
There are
10 types of people
who can understand binary.]]
}

contact {
-- some other contact
}

E序说明
* 把function和tablel合, 可以使Lua成ؓ一U类似XML的数据描q语a
* e09中contact{...}, 是一U函数的调用Ҏ, 不要弄؜?
* [[...]]是表C多行字W串的方?
* 当用C API时此U方式的优势更明? 其中contact{..}部分可以另外存成一配置?
?

4.试试?
x看哪些地方可以用Ce09中提到的配置Ҏ呢?

--

通过例子学习Lua(5) ---- Lua与C交互入门

1.?

Lua与C/C++l合是很紧密? Lua与C++交互是徏立在Lua与C的基上的, 所
以偶先从Lua与C讲v.

正如W一讲所? q行LuaE序或者说调用Lua主要有两U方?
* 通过命o行执?Lua"命o
* 通过Lua的C?
虽然此前偶们一直用W一U方? 但偶要告诉你, 通过Lua的C库执行才是游戏中
常用的方?

2.Lua的C?

Lua的C库可以做为Shared Library调用, 但一般开发游戏时会把Lua的所有源E序
都包含在? q不把Lua~译成共享库的Ş? 因ؓLuaE序只有100多K, 而且几乎
可以在Q何编译器下Clean Compile. 带Lua源程序的另一个好处时, 可以随时对Lua
本nq行扩充, 增加偶们所需的功?

Lua的C库提供一pdAPI:
* 理全局变量
* 理tables
* 调用函数
* 定义新函? q也可以完全由C实现
* 垃圾攉器Garbage collector, 虽然Lua可以自动q行, 但往往不是立即执行?
所以对实时性要求比较高的程? 会自p用垃圾收集器
* 载入q执行LuaE序, q也可以由Lua自n实现
* MLua可以实现的功? 都可以通过Lua的C API实现, q对于优化程序的q行速度
有帮? l常调用的共用的LuaE序片断可以转成CE序, 以提高效? qLua都是C写的
q有什么C不能实现?

3.Lua与C集成的例?
例e10.c
/* A simple Lua interpreter. */
#include <stdio.h>
#include <lua.h>
int main(int argc, char *argv[]) {
char line[BUFSIZ];
lua_State *L = lua_open(0);
while (fgets(line, sizeof(line), stdin) != 0)
lua_dostring(L, line);
lua_close(L);
return 0;
}

~译
Linux/Cygwin
* 先编译Lua, q把头文件放入include路径
* gcc e10.c -llua -llualib -o e10

VC6/VC2003
* 先编译Lua, 在Option中设|头文g和库文g路径
* 新徏工程,在工E配|中加入附加库lua.lib和lualib.lib
* ~译成exe

q行l果
本程序的功能是实C个Lua解释? 输入的每行字W都会被解释成Luaq执?

E序说明
* #include <lua.h> 包含lua头文? 然后才可以用API
* lua_State *L = lua_open(0) 打开一个Lua执行?
* fgets(line, sizeof(line), stdin) 从标准输入里d一?
* lua_dostring(L, line) 执行此行
* lua_close(L) 关闭Lua执行?


例e11.c
/* Another simple Lua interpreter. */
#include <stdio.h>
#include <lua.h>
#include <lualib.h>
int main(int argc, char *argv[]) {
char line[BUFSIZ];
lua_State *L = lua_open(0);
lua_baselibopen(L);
lua_iolibopen(L);
lua_strlibopen(L);
lua_mathlibopen(L);
while (fgets(line, sizeof(line), stdin) != 0)
lua_dostring(L, line);
lua_close(L);
return 0;
}

q行l果
本程序的功能是实C个Lua解释? 输入的每行字W都会被解释成Luaq执?
与上例不同的? 本例调用了Lua的一些标准库.

E序说明
* #include <lualib.h> 包含Lua的标准库
* 以下q几行是用来dLua的一些库, q样偶们的LuaE序可以有更多的功?
lua_baselibopen(L);
lua_iolibopen(L);
lua_strlibopen(L);
lua_mathlibopen(L);

4.试试?
把上面两个小例子在你熟悉的编译器中编译执? q试试能否与Lua源码树一L?

--
通过例子学习Lua(6) ---- C/C++中用Lua函数

参考英文文档http://tonyandpaige.com/tutorials/lua2.html

1.?
偶们q次主要说说怎么由Lua定义函数, 然后在C或者C++中调? q里偶们
暂不涉及C++的对象问? 只讨用函数的参数, q回值和全局变量的?

2.
q里偶们在e12.lua里先定义一个简单的add(), x,y为加法的两个参数,
return 直接q回相加后的l果.

例e12.lua
-- add two numbers
function add ( x, y )
return x + y
end

在前一ơ里, 偶们说到 lua_dofile() 可以直接在C中执行lua文g. 因ؓ偶们
q个E序里只定义了一个add()函数, 所以程序执行后q不直接l果, 效果相当
于在C中定义了一个函C?

Lua的函数可以有多个参数, 也可以有多个q回? q都是由?stack)实现?
需要调用一个函数时, 把q个函数压入? 然后序压入所有参? 然后?
lua_call()调用q个函数. 函数q回? q回g是存攑֜栈中. q个q程?
汇编执行函数调用的过E是一L.

例e13.cpp 是一个调用上面的Lua函数的例?
#include <stdio.h>

extern "C" { // q是个C++E序, 所以要extern "C",
// 因ؓlua的头文g都是C格式?
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

/* the Lua interpreter */
lua_State* L;

int luaadd ( int x, int y )
{
int sum;

/* the function name */
lua_getglobal(L, "add");

/* the first argument */
lua_pushnumber(L, x);

/* the second argument */
lua_pushnumber(L, y);

/* call the function with 2
arguments, return 1 result */
lua_call(L, 2, 1);

/* get the result */
sum = (int)lua_tonumber(L, -1);
lua_pop(L, 1);

return sum;
}

int main ( int argc, char *argv[] )
{
int sum;

/* initialize Lua */
L = lua_open();

/* load Lua base libraries */
lua_baselibopen(L);

/* load the script */
lua_dofile(L, "e12.lua");

/* call the add function */
sum = luaadd( 10, 15 );

/* print the result */
printf( "The sum is %d\n", sum );

/* cleanup Lua */
lua_close(L);

return 0;
}

E序说明:
main中过E偶们上ơ已l说q了, 所以这ơ只说说luaadd的过E?
* 首先用lua_getglobal()把add函数压栈
* 然后用lua_pushnumber()依次把x,y压栈
* 然后调用lua_call(), q且告诉E序偶们有两个参C个返回?
* 接着偶们从栈取回返回? 用lua_tonumber()
* 最后偶们用lua_pop()把返回值清?

q行l果:
The sum is 25

~译Ҏ
Linux下把E序存成e13.cpp
g++ e13.cpp -llua -llualib -o e13
./e13

VC下编译方?
* 首先建立一个空的Win32 Console Application Project
* 把e13.cpp加入工程?
* 点project setting,然后讄link选项, 再加上lua.lib lualib.lib两个额外的库
* 最后编?

建立好的project可以在这里下?
VC http://tonyandpaige.com/tutorials/luaadd.zip
Linux http://tonyandpaige.com/tutorials/luaadd.tar.gz

3.全局变量
上面偶们用到了lua_getglobal()但ƈ没有详细? q里偶们再D两个例子来说下全局
变量
lua_getglobal()的作用就是把lua中全局变量的值压入栈
lua_getglobal(L, "z");
z = (int)lua_tonumber(L, 1);
lua_pop(L, 1);
假设LuaE序中定义了一个全局变量z, q段程序就是把z的值取出放入C的变量z?

另外Lua中还有一个对应的函数lua_setglobal(), 作用是用栈顶的值填充指定的全局?
?
lua_pushnumber(L, 10);
lua_setglobal(L, "z");
例如q段程序就是把lua中的全局变量z设ؓ10, 如果lua中未定义z的话, ׃自动?
Z?
全局变量zq设?0.

4.试试?
自己写个函数用C/C++来调用下试试

--
通过例子学习Lua(7) ---- Lua中调用C/C++函数

1.前言
上次偶说CC/C++中调用Lua的函? 然后有朋友问从Lua中如何调用C/C++?
函数, 所以偶们这ơ就来说说这个问? 首先偶们会在C++中徏立一个函? 然后
告知Lua有这个函? 最后再执行? 另外, ׃函数不是在Lua中定义的, 所?
无法定函数的正? 可能在调用过E中会出? 因此偶们q会说说Lua出错?
理的问题.

2.Lua中调用C函数
在lua中是以函数指针的形式调用函数, q且所有的函数指针都必L_下此U?
cd:
typedef int (*lua_CFunction) (lua_State *L);

也就是说, 偶们在C++中定义函数时必须以lua_State为参? 以int回值才?
被Lua所调用. 但是不要忘记? 偶们的lua_State是支持栈? 所以通过栈可?
传递无I个参数, 大小只受内存大小限制. 而返回的intg只是指返回值的个数
真正的返回值都存储在lua_State的栈? 偶们通常的做法是做一个wrapper, ?
所有需要调用的函数都wrap一? q样可以调用Q意的函数?

下面q个例子是一个C++的average()函数, 它将展示如何用多个参数ƈq回多个?

例e14.cpp
#include <stdio.h>

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

/* the Lua interpreter */
lua_State* L;

static int average(lua_State *L)
{
/* get number of arguments */
int n = lua_gettop(L);
double sum = 0;
int i;

/* loop through each argument */
for (i = 1; i <= n; i++)
{
/* total the arguments */
sum += lua_tonumber(L, i);
}

/* push the average */
lua_pushnumber(L, sum / n);

/* push the sum */
lua_pushnumber(L, sum);

/* return the number of results */
return 2;
}

int main ( int argc, char *argv[] )
{
/* initialize Lua */
L = lua_open();

/* load Lua base libraries */
lua_baselibopen(L);

/* register our function */
lua_register(L, "average", average);

/* run the script */
lua_dofile(L, "e15.lua");

/* cleanup Lua */
lua_close(L);

return 0;
}

例e15.lua
-- call a C++ function

avg, sum = average(10, 20, 30, 40, 50)

print("The average is ", avg)
print("The sum is ", sum)


E序说明:
* lua_gettop()的作用是q回栈顶元素的序? ׃Lua的栈是从1开始编L,
所以栈元素的序号也相当于栈中的元素个? 在这? 栈中元素的个数就
是传入的参数个数.
* for循环计算所有传入参数的d. q里用到了数D{换lua_tonumber().
* 然后偶们用lua_pushnumber()把^均值和dpush到栈?
* 最? 偶们q回2, 表示有两个返回?
* 偶们虽然在C++中定义了average()函数, 但偶们的LuaE序q不知道, 所以需
要在main函数中加?

/* register our function */
lua_register(L, "average", average);

q两行的作用是告诉e15.lua有average()q样一个函?
* q个E序可以存成cpp也可以存成c, 如果?c为扩展名׃需要加extern "C"

~译的方法偶们上ơ说q了, Ҏ相同.
e15.lua执行的方法只能用上例中的C++中执? 而不能用命o行方式执?

3.错误处理
在上例中, 偶们没有对传入的参数是否为数字进行检? q样做不? 所以这里偶
们再加上错误处理的片?

把这D加在for循环之内:
if (!lua_isnumber(L, i)) {
lua_pushstring(L, "Incorrect argument to 'average'");
lua_error(L);
}
q段的作用就是检传入的是否为数?

加上q段之后, 偶们debug的时候就会简单许? 对于l合两种语言的编E? 它们?
间传递数据的正确性检是非常重要?

q里有别人写好的例子:
VC?http://tonyandpaige.com/tutorials/luaavg.zip
Linux?http://tonyandpaige.com/tutorials/luaavg.tar.gz

x, Lua与C的结合就基本讲完? 下次偶要开始说说Lua与面向对?
但是偶自p没有学完, 所以大家可能要多等两天? Sorry!

--



Render Donkey 2009-05-16 21:37 发表评论
]]>
字节填充函数http://www.shnenglu.com/Leaf/archive/2009/04/18/80320.htmlRender DonkeyRender DonkeySat, 18 Apr 2009 01:58:00 GMThttp://www.shnenglu.com/Leaf/archive/2009/04/18/80320.htmlhttp://www.shnenglu.com/Leaf/comments/80320.htmlhttp://www.shnenglu.com/Leaf/archive/2009/04/18/80320.html#Feedback0http://www.shnenglu.com/Leaf/comments/commentRss/80320.htmlhttp://www.shnenglu.com/Leaf/services/trackbacks/80320.html貌似是在?D游戏~程大师技巧》上看到的这两个函数Q当时觉得很牛Ӟ于是p下来了,不过至今没有怎么用到Q我想估计以后会有用吧?br>
//内嵌汇编的用?字节填充的函?br>inline  void Mem_Set_QUAD(VOID *dest, UINT data, int count )
{
     _asm
          {
           mov  edi, dest  ; edi指向目标内存
      mov  ecx, count  ;要移动的Q2位字?br>      mov  eax, data   ;Q2位数?br>      rep  stosd    ;Ud数据
     ?/end asm
 }//end Mem_Set_QUAD

//用于2字节QDWORD)数据填充的函?br>inline  void Mem_Set_WORD(VOID *dest, USHORT data, int count )
{
     _asm
          {
           mov  edi, dest  ; edi指向目标内存
      mov  ecx, count  ;要移动的16位字?br>      mov  ax, data   ;16位数?br>      rep  stosw    ;Ud数据
     ?/end asm
 }//end Mem_Set_WORD





Render Donkey 2009-04-18 09:58 发表评论
]]>
最原始Q最U朴的快速排序算?/title><link>http://www.shnenglu.com/Leaf/archive/2009/01/04/71134.html</link><dc:creator>Render Donkey</dc:creator><author>Render Donkey</author><pubDate>Sun, 04 Jan 2009 07:48:00 GMT</pubDate><guid>http://www.shnenglu.com/Leaf/archive/2009/01/04/71134.html</guid><wfw:comment>http://www.shnenglu.com/Leaf/comments/71134.html</wfw:comment><comments>http://www.shnenglu.com/Leaf/archive/2009/01/04/71134.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Leaf/comments/commentRss/71134.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Leaf/services/trackbacks/71134.html</trackback:ping><description><![CDATA[<p> </p> <p><br>int Partition(int a[],int l,int r)<br>{<br> int p = a[l];//取首元素作ؓ划分?/p> <p> while(l<r)<br> {<br>  while(l<r&& a[r]>=p)<br>   --r;<br>  a[l] = a[r];</p> <p>  while(l<r&& a[l]<=p)<br>   ++l;<br>  a[r] = a[l];<br> }<br> a[l] = p;<br> return l;<br>}</p> <p>void QSort(int a[],int l,int r)<br>{<br> int p;<br> if(l<r)<br> {<br>  p = Partition(a,l,r);<br>  for(int i = l; i< r;++i)<br>  {<br>   cout<<a[i]<<" ";<br>  }<br>  cout<<endl;</p> <p>  QSort(a,l,p-1);<br>  QSort(a,p+1,r);<br> }<br>}</p> <img src ="http://www.shnenglu.com/Leaf/aggbug/71134.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Leaf/" target="_blank">Render Donkey</a> 2009-01-04 15:48 <a href="http://www.shnenglu.com/Leaf/archive/2009/01/04/71134.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.517banjia.cn" target="_blank">þֻоƷƵ99</a>| <a href="http://www.ccjump.cn" target="_blank">þþƷ99þ㽶</a>| <a href="http://www.jihejingjia.cn" target="_blank">þþƷŷƬ</a>| <a href="http://www.4wfgg.cn" target="_blank">ŷ˾þþƷ</a>| <a href="http://www.80xz.cn" target="_blank">97þù¶Ʒ</a>| <a href="http://www.mdwmp.com.cn" target="_blank">99þþƷһ</a>| <a href="http://www.smmz.com.cn" target="_blank">99reþþƷҳ2020</a>| <a href="http://www.shoescaps.cn" target="_blank">þ91ƷۺϹҳ</a>| <a href="http://www.wy369.com.cn" target="_blank">ݺɫþۺѿ</a>| <a href="http://www.chuidu.cn" target="_blank">ҹþþþ</a>| <a href="http://www.yzlxdr.cn" target="_blank">ƷȾþëƬ</a>| <a href="http://www.gsm777.cn" target="_blank">þþƷAVþþ</a>| <a href="http://www.dlygbx.cn" target="_blank">þ㽶߿ۿ</a>| <a href="http://www.sf789.com.cn" target="_blank">þþƷƵһ</a>| <a href="http://www.yrdfund.com.cn" target="_blank">ƷƷþþþ </a>| <a href="http://www.msomso.cn" target="_blank">ݺɫþþۺ</a>| <a href="http://www.wubaili.com.cn" target="_blank">޾Ʒþþþþο</a>| <a href="http://www.huangjiguang.cn" target="_blank"> þۺϺݺۺϾþü </a>| <a href="http://www.ulpj.cn" target="_blank">þĻ</a>| <a href="http://www.03caiji.cn" target="_blank">Ʒ˾þþþþþ</a>| <a href="http://www.taskbee.cn" target="_blank">ɫվ޷ľþò</a>| <a href="http://www.shgdb.cn" target="_blank">þþ</a>| <a href="http://www.aving.com.cn" target="_blank">ƷþþþþóAV</a>| <a href="http://www.cz27b1.cn" target="_blank">97Ƶþþ</a>| <a href="http://www.d5430.cn" target="_blank">Ļ˾þ</a>| <a href="http://www.023pet.cn" target="_blank">Ʒvaþþþþþ</a>| <a href="http://www.osgh.cn" target="_blank">޹Ʒþ</a>| <a href="http://www.t8s.com.cn" target="_blank">99ƷþþƷһ</a>| <a href="http://www.odbeqi.cn" target="_blank">žžƷ99þþ㽶</a>| <a href="http://www.s5273.cn" target="_blank">þþþŷղAV</a>| <a href="http://www.tduck.cn" target="_blank">þþ</a>| <a href="http://www.hgd625028888.cn" target="_blank">þþþ99ƷƬţţӰ</a>| <a href="http://www.mz025.cn" target="_blank">ҹþӰԺ</a>| <a href="http://www.vnxz.cn" target="_blank">ھƷþþþþ鶹</a>| <a href="http://www.tvjay.cn" target="_blank">Ʒ99þþþþwww</a>| <a href="http://www.vzrg.cn" target="_blank">ۺϾþúݺɫ99h</a>| <a href="http://www.mdwmp.com.cn" target="_blank">þˬˬAV</a>| <a href="http://www.gh688.cn" target="_blank">þþƷa޹v岻</a>| <a href="http://www.zheiwa.cn" target="_blank">ձǿƬþþþþAAA </a>| <a href="http://www.game839.cn" target="_blank">þӰԺһ</a>| <a href="http://www.ssfbq5.cn" target="_blank">ճˮþ޾Ʒtv</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>