﻿<?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/deadpunk/</link><description>我没有技术</description><language>zh-cn</language><lastBuildDate>Thu, 23 Apr 2026 10:15:20 GMT</lastBuildDate><pubDate>Thu, 23 Apr 2026 10:15:20 GMT</pubDate><ttl>60</ttl><item><title>转载：Python内置的字符串处理函数整理</title><link>http://www.cppblog.com/deadpunk/archive/2012/08/13/187035.html</link><dc:creator>活着就是折腾，所以当然要骠悍的折腾</dc:creator><author>活着就是折腾，所以当然要骠悍的折腾</author><pubDate>Mon, 13 Aug 2012 01:18:00 GMT</pubDate><guid>http://www.cppblog.com/deadpunk/archive/2012/08/13/187035.html</guid><wfw:comment>http://www.cppblog.com/deadpunk/comments/187035.html</wfw:comment><comments>http://www.cppblog.com/deadpunk/archive/2012/08/13/187035.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deadpunk/comments/commentRss/187035.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deadpunk/services/trackbacks/187035.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 字符串长度获取：len(str)例：print '%s length=%d' % (str,len(str))字母处理全部大写：str.upper()全部小写：str.lower()大小写互换：str.swapcase()首字母大写，其余小写：str.capitalize()首字母大写：str.title()print '%s lower=%s' % (str,str.lower())print ...&nbsp;&nbsp;<a href='http://www.cppblog.com/deadpunk/archive/2012/08/13/187035.html'>阅读全文</a><img src ="http://www.cppblog.com/deadpunk/aggbug/187035.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deadpunk/" target="_blank">活着就是折腾，所以当然要骠悍的折腾</a> 2012-08-13 09:18 <a href="http://www.cppblog.com/deadpunk/archive/2012/08/13/187035.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转载: 获取Console Window的窗口句柄的三种方法</title><link>http://www.cppblog.com/deadpunk/archive/2010/12/16/136622.html</link><dc:creator>活着就是折腾，所以当然要骠悍的折腾</dc:creator><author>活着就是折腾，所以当然要骠悍的折腾</author><pubDate>Thu, 16 Dec 2010 05:54:00 GMT</pubDate><guid>http://www.cppblog.com/deadpunk/archive/2010/12/16/136622.html</guid><wfw:comment>http://www.cppblog.com/deadpunk/comments/136622.html</wfw:comment><comments>http://www.cppblog.com/deadpunk/archive/2010/12/16/136622.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deadpunk/comments/commentRss/136622.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deadpunk/services/trackbacks/136622.html</trackback:ping><description><![CDATA[<font  color="#333333" face="Arial"><span  style="font-size: 12px; line-height: 18px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;"><p style="line-height: normal; ">——————— 【 转载请保留 】 ———————</p><p style="line-height: normal; ">作者：Defanive<br style="line-height: normal; ">博客：Console.Dec.Cn（Hi.Baidu.Com/Console_App）</p><p style="line-height: normal; ">——————— 【 谢谢合作 】 ———————</p><p style="line-height: normal; ">类型：原创<br style="line-height: normal; ">时间：09.03.21<br style="line-height: normal; ">测试环境：VC++ 6.0</p><p style="line-height: normal; ">窗口，都有其唯一的句柄（hWnd）。得到了窗口句柄，能够做很多事情。控制台程序，若能在窗口效果上下文章，那么这个第三方工具将会很成功。</p><p style="line-height: normal; ">网上给出的常用方法：</p><p style="line-height: normal; ">HWND hw=FindWindow("ConsoleWindowClass",NULL);</p><p style="line-height: normal; ">这不失为一个好方法，但是单从Class方面入手保险度不高。</p><p style="line-height: normal; ">API函数FindWindow有两个参数，类名与窗口标题。当不提供窗口标题的时候，返回的句柄为同类窗口中Z序最高的窗口句柄。虽然说执行只是一瞬间，但是保险起见，还是提供下标题窗口，更保险。</p><p style="line-height: normal; ">char strTitle[255];<br style="line-height: normal; ">GetConsoleTitle(strTitle, 255);<br style="line-height: normal; ">HWND hw=FindWindow("ConsoleWindowClass",strTitle);</p><p style="line-height: normal; ">当然，如果要精益求精，还有更保险的办法，用 Kernel32.dll 中部分未公布的API。在用 eXeScope 导出 Kernel32.dll 中控制台相关的API之后，发现有一个名为GetConsoleWindow的API。查找参考了部分资料后，提供如下代码，能够动态载入这个API并获得窗口句柄。</p><p style="line-height: normal; ">首先需要全局声明：</p><p style="line-height: normal; ">typedef HWND (WINAPI *PROCGETCONSOLEWINDOW)();<br style="line-height: normal; ">PROCGETCONSOLEWINDOW GetConsoleWindow;</p><p style="line-height: normal; ">然后再Main()函数开头中输入以下内容：</p><p style="line-height: normal; ">HMODULE hKernel32 = GetModuleHandle("kernel32");<br style="line-height: normal; ">GetConsoleWindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");</p><p style="line-height: normal; ">完成了动态载入API函数GetConsoleWindow的任务。需要使用时可如下：</p><p style="line-height: normal; ">HWND cmd=GetConsoleWindow();</p><p style="line-height: normal; ">个人认为，使用API函数GetConsoleWindow是最安全，也是最好的方法。在更大的控制台编程中，可能随时需要用到AttachConsole来改变程序的宿主控制台，这个时候再用前两种方法就不够好了。尽管载入的代码很长，但是通用性更高。</p><p style="line-height: normal; "><strong style="line-height: normal; ">范例下载地址：<br style="line-height: normal; "></strong><a href="http://www.qupan.com/down/defanive_3030830.html" style="color: rgb(20, 141, 214); line-height: normal; text-decoration: none; "><strong style="line-height: normal; ">http://www.qupan.com/down/defanive_3030830.html</strong></a></p><p style="line-height: normal; ">——————— 【 转载请保留 】 ———————</p><p style="line-height: normal; ">作者：Defanive<br style="line-height: normal; ">博客：Console.Dec.Cn（Hi.Baidu.Com/Console_App）</p><p style="line-height: normal; ">——————— 【 谢谢合作 】 ———————</p></span></font><img src ="http://www.cppblog.com/deadpunk/aggbug/136622.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deadpunk/" target="_blank">活着就是折腾，所以当然要骠悍的折腾</a> 2010-12-16 13:54 <a href="http://www.cppblog.com/deadpunk/archive/2010/12/16/136622.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转载：VC窗口启动时隐藏</title><link>http://www.cppblog.com/deadpunk/archive/2009/03/03/75377.html</link><dc:creator>活着就是折腾，所以当然要骠悍的折腾</dc:creator><author>活着就是折腾，所以当然要骠悍的折腾</author><pubDate>Tue, 03 Mar 2009 02:06:00 GMT</pubDate><guid>http://www.cppblog.com/deadpunk/archive/2009/03/03/75377.html</guid><wfw:comment>http://www.cppblog.com/deadpunk/comments/75377.html</wfw:comment><comments>http://www.cppblog.com/deadpunk/archive/2009/03/03/75377.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deadpunk/comments/commentRss/75377.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deadpunk/services/trackbacks/75377.html</trackback:ping><description><![CDATA[原帖地址：<a href="http://hi.baidu.com/edudo/blog/item/33c898f31428c8cd0b46e0d4.html">http://hi.baidu.com/edudo/blog/item/33c898f31428c8cd0b46e0d4.html</a><br><br>对于这类问题，大家最容易想到的可能就是在PreCreateWindow中添加cs.style &amp;=~WS_VISIBLE;这是不可行的。程序仍可使用ShowWindow()将窗体显示出来.<br>
<p>1.基于对话框的程序<br>&nbsp;&nbsp; 我在论坛上看到有人说在OnInitDialog()中加上ShowWindow(SW_HIDE)对话框便不出现了，其实是不可行的。至于原因，我认为是系统是在OnInitDialog()后调用ShowWindow(SW_SHOW)让对话框显示的.可以添加下面代码:<br>CXXDlg::OnInitDialog()<br>{<br>... <br>Sleep(5000);<br>return TRUE;<br>} <br>可以发现5秒后对话框才显示出来.至于在何时调用的我也不清楚，但是我们可以在OnPaint()中加上ShowWindow(SW_HIDE),来达到隐藏的目的.不过使用的这种方法，会有一点闪烁.另外一种方法就是在OnInitDialog()中使用SetWindowPlacement()</p>
<br>
<p>GetWindowPlacement(&amp;m_wp); //恢复时用<br>ModifyStyleEx(WS_EX_APPWINDOW,WS_EX_TOOLWINDOW);//从任务栏中去掉.</p>
<br>
<p>WINDOWPLACEMENT wp;<br>wp.length=sizeof(WINDOWPLACEMENT);<br>wp.flags=WPF_RESTORETOMAXIMIZED;<br>wp.showCmd=SW_HIDE;<br>SetWindowPlacement(&amp;wp);</p>
<br>
<p>还有一种更简单的方法:在OnInitDialog()中调用下面代码.<br>SetWindowPos(&amp;wndTop,0,0,0,0,NULL);</p>
<br>
<p>2.基于单文档的程序</p>
<br>
<p>我们一般采用的方法就是将InitInstance()中的:<br>CXXApp::InitInstance()<br>{<br>&nbsp;&nbsp; //m_pMainWnd-&gt;ShowWindow(SW_SHOW);<br>}<br>但是这样窗体还会有闪烁。<br>因为MFC还要在ActiveFrame显示框架，所以我们还需要添加下面代码:<br>void CMainFrame::ActivateFrame(int nCmdShow) <br>{<br>&nbsp;&nbsp; nCmdShow=SW_HIDE;<br>&nbsp;&nbsp; CFrameWnd::ActivateFrame(nCmdShow);<br>}<br>或者:<br>int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)<br>{<br>&nbsp;&nbsp; AfxGetApp()-&gt;m_nCmdShow=SW_HIDE;<br>}<br>顺便说一下，上面通过ModifyStyleEx(WS_EX_APPWINDOW,WS_EX_TOOLWINDOW)的方法来实现从任务栏去掉按钮，这样当显示时还要切换显示的模式，其实还可以通过调用TaskbarList组件直接删除和添加:<br>ITaskbarList的定义在shobjidl.h(vs.net)中。<br>也可以手动定义:<br>DECLARE_INTERFACE_(ITaskbarList,IUnknown)<br>{<br>&nbsp;&nbsp; STDMETHOD(QueryInterface)(THIS_ REFIID riid,LPVOID* ppvObj) PURE;<br>&nbsp;&nbsp; STDMETHOD_(ULONG,AddRef)(THIS) PURE;<br>&nbsp;&nbsp; STDMETHOD_(ULONG,Release)(THIS) PURE;<br>&nbsp;&nbsp; STDMETHOD(ActivateTab)(HWND) PURE;<br>&nbsp;&nbsp; STDMETHOD(AddTab)(HWND) PURE;<br>&nbsp;&nbsp; STDMETHOD(DeleteTab)(HWND) PURE;<br>&nbsp;&nbsp; STDMETHOD(HrInit)(void) PURE;<br>};<br>BOOL CMy2App::InitInstance()<br>{ <br>&nbsp;&nbsp; CoInitialize(0);<br>&nbsp;&nbsp; ITaskbarList *pObj;<br>&nbsp;&nbsp; CoCreateInstance(CLSID_TaskbarList,NULL,CLSCTX_INPROC_SERVER,IID_ITaskbarList,(void**)&amp;pObj);<br>&nbsp;&nbsp; pObj-&gt;DeleteTab(m_pMainWnd-&gt;m_hWnd); //从任务栏上删除<br>&nbsp;&nbsp; //pObj-&gt;AddTab(m_pMainWnd-&gt;m_hWnd); //添加</p>
<br>
<p>&nbsp;&nbsp; pObj-&gt;Release();<br>&nbsp;&nbsp; CoUninitialize();<br>}</p>
<br>
<p>所以我们还可以用将窗体最小化,并从任备栏上删除按钮的方法来实现隐藏.</p>
<p>&#160;</p>
<p>有很多应用程序要求一起动就隐藏起来，这些程序多作为后台程序运行，希望不影响其他窗口，往往只在托盘区显示一个图标。这些程序通常都是对话框程序，而对话框在初始化的过程上与SDI、MDI的初始化是不同的，对话框只需要DoModule或者是CreateDialog等等对话框函数调用一次便可，SDI、MDI则要好几步才行。这样看来，对话框在使用方法上面是隐藏了不少细节的，其中就没有SDI、MDI所要求的ShowWindow(nCmdShow)这一步。因此对话框要想一运行就隐藏，并不是很直接的。有一些方法可以做到这一点，下面我们就来看看几种方案。 <br><br>1．定时器 <br>最直观，又是最无奈的一个方法就是使用定时器。既然我们在对话框开始显示之前不能用ShowWindow(SW_HIDE)将其隐藏，那就给一个时间让它显示，完了我们在隐藏它。 <br><br>方法： <br><br>1.在OnInitDialog()函数里设置定时器：（WINDOWS API里面响应消息WM_INITDIALOG） <br><br>SetTimer(1, 1, NULL); <br><br>2.添加处理WM_TIMER的消息处理函数OnTimer,添加代码： <br><br>if(nIDEvent == 1) <br><br>{ <br><br>DeleteTimer(1); <br><br>ShowWindow(SW_HIDE); <br><br>} <br><br>这种方法的缺点是显而易见的，使用定时器，使得程序的稳定性似乎打一个折扣；窗口是要先显示出来的，那么效果就是窗口闪了一下消失。 <br><br>2．改变对话框显示状况 <br>在对话框初始化时改变其显示属性可以让它隐藏起来。方法是调用SetWindowPlacement函数： <br><br><br>BOOL CDialogExDlg::OnInitDialog() <br><br>{ <br><br>CDialog::OnInitDialog(); <br><br>//DO something <br><br><br>WINDOWPLACEMENT wp; <br><br>wp.length=sizeof(WINDOWPLACEMENT); <br><br>wp.flags=WPF_RESTORETOMAXIMIZED; <br><br>wp.showCmd=SW_HIDE; <br><br>SetWindowPlacement(&amp;wp); <br><br>return TRUE; <br><br>} <br><br><br><br>在需要显示时（通常是响应热键或者托盘图标的鼠标消息）： <br><br><br>WINDOWPLACEMENT wp; <br><br>wp.length=sizeof(WINDOWPLACEMENT); <br><br>wp.flags=WPF_RESTORETOMAXIMIZED; <br><br>wp.showCmd=SW_SHOW; <br><br>SetWindowPlacement(&amp;wp); <br><br><br>这样的效果很不理想：窗口显示在屏幕的左上角，并且是只有标题栏，要正常显示，还需加上如下代码： <br><br>定义一个成员变量CRect rect; <br><br>在OnInitDialog()里面： <br><br>GetWindowRect(&amp;rect); <br><br>在需要显示的地方： <br><br>SetWindowPos(&amp;wndNoTopMost, wndRc.left, wndRc.top, wndRc.right, wndRc.bottom, SWP_SHOWWINDOW); <br><br>CenterWindow(); <br><br>即使这样，效果还是很差。 <br><br>这种方法还有一个弊端是当程序开始运行并且隐藏起来后，原来激活的窗口变成了非激活状态了，而当对话框显示出来后，对话框自身也是非激活状态的。 <br><br><br>3．不绘制窗口 <br>当对话框显示时将要响应消息WM_PAINT绘制客户区，相应消息WM_NCPAINT绘制窗口边框。我们在窗口第一次自绘自身时隐藏窗口，可以收到比较良好的效果。由于窗口是先画窗口边框，所以我们仅需处理WM_NCPAINT即可。代码如下： <br><br>添加WM_NCPAINT处理函数。 <br><br>void CMyDialog::OnNcPaint() <br><br>{ <br><br>static int i = 2; <br><br>if(i &gt; 0) <br><br>{ <br><br>i --; <br><br>ShowWindow(SW_HIDE); <br><br>} <br><br>else <br><br>CDialog::OnNcPaint(); <br><br>} <br><br>这里有个问题：为什么要定义静态变量i而且设其值为2呢？ <br><br>我们只要窗口隐藏第一次，所以定义这个变量可以判断是否时首次显示窗口。当程序开始运行时，系统发送（SendMessage）WM_NCPAINT消息，此时程序的窗口边框应该被显示，但是此时我们没有作任何显示的操作，而是将窗口隐藏，ShowWindow(SW_HIDE)将把窗口的WS_VISIBLE属性去掉，继续执行，程序将检查WS_VISIBLE属性，如果没有则显示窗口，所以又发送了一个WM_NCPAINT消息。所以我们要处理两次WM_NCPAINT消息。 <br><br>在需要窗口显示时，调用ShowWindow(SW_SHOW)即可。 <br><br>程序执行的结果是，原来处于激活状态的窗口可能会闪动两下，然后仍然处于激活状态。这种处理方式比上面的方式要优越得多。 <br><br><br>4．将对话框作为子窗口 <br>这种方法是采用SDI框架，主窗口始终隐藏，对话框作为主窗口的成员变量，在CMainFrame::OnCreate()里面加入下代码： <br><br>if(!dlg.Create(IDD_MYDIALOG, this)) <br><br>{ <br><br>return &#8211;1; <br><br>} <br><br>dlg.ShowWindow(SW_HIDE); <br><br>在要显示对话框的地方用dlg.ShowWindow(SW_SHOW);即可。注意，主窗口一定要隐藏，否则对话框可能会闪现一下。 <br><br>隐藏状态栏窗口 <br>上面介绍了几种检查对话框的方法，大家如果试过的话可能已经注意到系统状态栏里在程序启动时会有程序的图标闪过，在隐藏对话框的时候这个也是要隐藏的，方法很简单： <br><br>在OnInitDialog()函数里面加上ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW);即可。在要显示窗口的地方加上代码ModifyStyleEx(WS_EX_TOOLWINDOW, WS_EX_APPWINDOW);即将窗口的扩展样式改回来。 <br><br></p>
<img src ="http://www.cppblog.com/deadpunk/aggbug/75377.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deadpunk/" target="_blank">活着就是折腾，所以当然要骠悍的折腾</a> 2009-03-03 10:06 <a href="http://www.cppblog.com/deadpunk/archive/2009/03/03/75377.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转载)了解 Boost Filesystem Library</title><link>http://www.cppblog.com/deadpunk/archive/2008/11/23/67670.html</link><dc:creator>活着就是折腾，所以当然要骠悍的折腾</dc:creator><author>活着就是折腾，所以当然要骠悍的折腾</author><pubDate>Sun, 23 Nov 2008 08:31:00 GMT</pubDate><guid>http://www.cppblog.com/deadpunk/archive/2008/11/23/67670.html</guid><wfw:comment>http://www.cppblog.com/deadpunk/comments/67670.html</wfw:comment><comments>http://www.cppblog.com/deadpunk/archive/2008/11/23/67670.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deadpunk/comments/commentRss/67670.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deadpunk/services/trackbacks/67670.html</trackback:ping><description><![CDATA[<blockquote>作者:<a href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#author" cmimpressionsent="1"><font color=#996699>Arpan Sen</font></a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#97;&#114;&#112;&#97;&#110;&#64;&#115;&#121;&#110;&#99;&#97;&#100;&#46;&#99;&#111;&#109;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#20102;&#35299;&#32;&#66;&#111;&#111;&#115;&#116;&#32;&#70;&#105;&#108;&#101;&#115;&#121;&#115;&#116;&#101;&#109;&#32;&#76;&#105;&#98;&#114;&#97;&#114;&#121;" cmimpressionsent="1"><font color=#5c81a7>arpan@syncad.com</font></a>), 技术负责人, Synapti Computer Aided Design Pvt Ltd<br><a title="Boost FileSystem" href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/" target=_blank><font color=#1d58d1>来源:http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/<br></font></a>缺乏定义良好的、用于处理文件系统操作的库，这一直是 <code>C++</code> 语言存在的一个问题。过去，程序员必须使用本机 API 来解决此问题。通过本文您将了解一个提供安全、可移植且易用的 <code>C++</code> 接口来促进文件系统操作的库：Boost Filesystem Library。 </blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
<p><code>C++</code> 语言（实际上是 <code>C++</code> 标准）的最常见问题之一是，缺乏定义良好的库来帮助处理文件系统查询和操作。由于这个原因，程序员不得不使用本机操作系统提供的应用程序编程接口（Application Program Interfaces，API），而这使得代码不能在平台之间移植。以下面的简单情况为例：您需要确定某个文件是否是 Directory 类型。在 Microsoft&#174; Windows&#174; 平台中，可以通过调用 <code>GetAttributes</code> 库函数（在 windows.h 头文件中定义）进行此操作： </p>
<table cellSpacing=0 cellPadding=0 width="65%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>DWORD GetFileAttributes (LPCTSTR <em>lpFileName</em>);
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>对于目录，所得到的结果应该为 FILE_ATTRIBUTE_DIRECTORY，而您的代码必须检查是否为此结果。在 UNIX&#174; 和 Linux&#174; 平台上，可以通过使用 <code>stat</code> 或 <code>fstat</code> 函数及 sys/stat.h 中定义的 S_ISDIR 宏来实现相同的功能。您还必须理解 <code>stat</code> 结构。下面是对应的代码： </p>
<table cellSpacing=0 cellPadding=0 width="65%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>#include &lt;sys/stat.h&gt;
            #include &lt;stdio.h&gt;
            int main()
            {
            struct stat s1;
            int status = stat(&lt;const char* denoting pathname&gt;, &amp;s1);
            printf(&#8220;Path is a directory : %d\n&#8221;, S_ISDIR(s1.st_mode));
            return 0;
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>对于 I/O 操作较多的程序，这样的不一致就意味着需要进行大量的工程工作才能在平台间移植代码。正是因为这个原因，我们才引入了 Boost Filesystem Library。这个广泛使用的库提供了安全、可移植且易用的 <code>C++</code> 接口，用于执行文件系统操作。可以从 <a href="http://www.boost.org/libs/filesystem" cmimpressionsent="1"><font color=#5c81a7>Boost</font></a> 站点免费下载此库。 </p>
<p><a name=N10096><font color=#1d58d1><span class=atitle>使用 boost::filesystem 的第一个程序</span> </font></a></p>
<p>在深入研究 Boost Filesystem Library 的更多细节之前，请看一下<a href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#list1" cmimpressionsent="1"><font color=#996699>清单 1</font></a> 中所示的代码；此代码使用 Boost API 确定某个文件的类型是否为 Directory。 </p>
<br><a name=list1><font color=#1d58d1><strong>清单 1. 用于确定某个文件的类型是否为 Directory 的代码</strong> </font></a><br>
<table cellSpacing=0 cellPadding=0 width="65%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>
            #include &lt;stdio.h&gt;
            #include &#8220;boost/filesystem.hpp&#8221;
            int main()
            {
            boost::filesystem::path path("/usr/local/include"); // random pathname
            bool result = boost::filesystem::is_directory(path);
            printf(&#8220;Path is a directory : %d\n&#8221;, result);
            return 0;
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>此代码非常明了易懂，您并不需要了解任何系统特定的例程。此代码经过验证，能在不用修改的情况下在 gcc-3.4.4 和 cl-13.10.3077 上成功编译。 </p>
<br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"> <br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0> </td>
        </tr>
    </tbody>
</table>
<table class=no-print cellSpacing=0 cellPadding=0 align=right>
    <tbody>
        <tr align=right>
            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"> <br>
            <table cellSpacing=0 cellPadding=0 border=0>
                <tbody>
                    <tr>
                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0> <br></td>
                        <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#main" cmimpressionsent="1"><strong><font color=#996699>回页首</font><font color=#1d58d1> </font></strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name=N100AF><font color=#1d58d1><span class=atitle>了解 Boost path 对象</span> </font></a></p>
<p>了解 Boost Filesystem Library 的关键是 <code>path</code> 对象，因为 Filesystem Library 中定义的多个例程都要对相应的 <code>path</code> 对象操作。文件系统路径通常依赖于操作系统。例如，众所周知，UNIX 和 Linux 系统使用正斜杠 (<code> /</code>) 字符作为目录分隔符，而 Windows 将反斜杠 (<code>\</code>) 字符用于类似的用途。<code>boost::filesystem::path</code> 旨在准确地抽象此特性。<code>path</code> 对象可以通过多种方式进行初始化，最常见的方式是使用 <code>char*</code> 或 <code>std::string</code> 进行初始化，如<a href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#list2" cmimpressionsent="1"><font color=#996699>清单 2</font></a> 中所示。 </p>
<br><a name=list2><font color=#1d58d1><strong>清单 2. 创建 Boost path 对象的方法</strong> </font></a><br>
<table cellSpacing=0 cellPadding=0 width="65%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>
            path(); // empty path
            path(const char* pathname);
            path(const std::string&amp; pathname);
            path(const char* pathname, boost::filesystem::path::name_check checker);
            path(const char* pathname, boost::filesystem::path::name_check checker);
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>在初始化 <code>path</code> 对象时，可以采用本机格式或可移植操作系统接口（Portable Operating System Interface，POSIX）委员会定义的可移植格式提供 PATHNAME 变量。这两种方法在实际中各有优缺点。考虑以下情况：您希望操作软件所创建的目录，此目录在 UNIX 和 Linux 系统上位于 /tmp/mywork，而在 Windows 上位于 C:\tmp\mywork。可以采用多种方法处理问题。<a href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#list3" cmimpressionsent="1"><font color=#996699>清单 3</font></a> 显示了面向本机格式的方法。 </p>
<br><a name=list3><font color=#1d58d1><strong>清单 3. 使用本机格式初始化 path</strong> </font></a><br>
<table cellSpacing=0 cellPadding=0 width="65%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>
            #ifdef UNIX
            boost::filesystem::path path("/tmp/mywork");
            #else
            boost::filesystem::path path("C:\\tmp\\mywork ");
            #endif
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>需要单个 <code>#ifdef</code> 来按操作系统初始化 path 对象。不过，如果您喜欢使用可移植格式，请参见<a href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#list4" cmimpressionsent="1"><font color=#996699>清单 4</font></a>。 </p>
<br><a name=list4><font color=#1d58d1><strong>清单 4. 使用可移植格式初始化 path</strong> </font></a><br>
<table cellSpacing=0 cellPadding=0 width="65%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>
            boost::filesystem::path path("/tmp/mywork");
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>请注意，<code>path::name_check</code> 指的是一个名称检查函数原型。如果其参数输入 PATHNAME 对于特定的操作系统或文件系统有效，名称检查函数将返回&#8220;True&#8221;。Boost Filesystem Library 提供了多个名称检查函数，而且也欢迎您提供自己的变体。常用的名称检查函数是 Boost 提供的 <code>portable_posix_name</code> 和 <code>windows_name</code>。 </p>
<br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"> <br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0> </td>
        </tr>
    </tbody>
</table>
<table class=no-print cellSpacing=0 cellPadding=0 align=right>
    <tbody>
        <tr align=right>
            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"> <br>
            <table cellSpacing=0 cellPadding=0 border=0>
                <tbody>
                    <tr>
                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0> <br></td>
                        <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#main" cmimpressionsent="1"><strong><font color=#996699>回页首</font><font color=#1d58d1> </font></strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name=N1011E><font color=#1d58d1><span class=atitle>path 成员函数概述</span> </font></a></p>
<p><code>path</code> 对象提供了多个成员方法。这些成员例程并不会修改文件系统，但会根据 path 名称提供有用的信息。此部分提供了其中几个例程的概述： </p>
<ul>
    <li><strong><code>const std::string&amp; string( )</code>：</strong>此例程会返回用于初始化 path 的字符串的副本，其格式符合 path 语法规则。
    <li><strong><code>std::string root_directory( )</code>：</strong>在提供了路径的情况下，此 API 将返回根目录，否则将返回空字符串。例如，如果路径包含 <em>/tmp/var1</em>，则此例程将返回 <code>/</code>，即 UNIX 文件系统的根。不过，如果路径是相对路径，如 <em>../mywork/bin</em>，此例程将返回空字符串。
    <li><strong><code>std::string root_name( )</code>：</strong>在给定从文件系统根目录开始的路径的情况下，此例程将返回包含 PATHNAME 的第一个字符的字符串。
    <li><strong><code>std::string leaf( )</code>：</strong>在给定绝对路径名称（例如，/home/user1/file2）的情况下，此例程将提供与文件名称对应的字符串（即 file2）。
    <li><strong><code>std::string branch_path( )</code>：</strong>这是与 <code>leaf</code> 互补的例程。在给定路径的情况下，将会返回其构造所用的所有元素（除了最后一个元素）。例如，对于使用 <em>/a/b/c</em> 初始化的 path，<code>path.branch_path( )</code> 将返回 <code>/a/b</code>。对于包含单个元素的路径，如 <em>c</em>，此例程将返回空字符串。
    <li><strong><code>bool empty( )</code>：</strong>如果 path 对象包含空字符串（例如 <em>path path1("")</em>），则此例程将返回 True。
    <li><strong><code>boost::filesystem::path::iterator</code>：</strong>此例程用于遍历 path 的各个元素。请看<a href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#list5" cmimpressionsent="1"><font color=#996699>清单 5</font></a> 所示的代码。 <br><br><a name=list5><strong><font color=#1d58d1>清单 5. 使用 path::iterator（begin 和 end 接口）</font></strong></a><br>
    <table cellSpacing=0 cellPadding=0 width="65%" border=0>
        <tbody>
            <tr>
                <td class=code-outline>
                <pre class=displaycode>
                #include &lt;iostream&gt;
                #include &#8220;boost/filesystem.hpp&#8221;
                int main()
                {
                boost::filesystem::path path1("/usr/local/include"); // random pathname
                boost::filesystem::path::iterator pathI = path1.begin();
                while (pathI != path1.end())
                {
                std::cout &lt;&lt; *pathI &lt;&lt; std::endl;
                ++pathI;
                }
                return 0;
                }
                // result: 1
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br>
    <p>上述程序的输出依次是 <code>/</code>、<code>usr</code>、<code>local</code>、<code>include</code>，代表了该目录的层次结构。 </p>
    <li><strong><code>path operator / (char* lhs, const path&amp; rhs)</code>：</strong>此例程是 <code>path</code> 的非成员函数。它将返回使用 <code>lhs</code> 和 <code>rhs</code> 形成的路径的串联值。它将自动插入 <code>/</code> 作为路径分隔符，如<a href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#list6" cmimpressionsent="1"><font color=#996699>清单 6</font></a> 中所示。 <br><br><a name=list6><strong><font color=#1d58d1>清单 6. 路径字符串的串联</font></strong></a><br>
    <table cellSpacing=0 cellPadding=0 width="65%" border=0>
        <tbody>
            <tr>
                <td class=code-outline>
                <pre class=displaycode>
                #include &lt;iostream&gt;
                #include &#8220;boost/filesystem.hpp&#8221;
                int main()
                {
                boost::filesystem::path path1("/usr/local/include"); // random pathname
                boost::filesystem::path::iterator pathI = path1.begin();
                while (pathI != path1.end())
                {
                std::cout &lt;&lt; *pathI &lt;&lt; std::endl;
                ++pathI;
                }
                return 0;
                }
                // result: 1
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br></li>
</ul>
<br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"> <br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0> </td>
        </tr>
    </tbody>
</table>
<table class=no-print cellSpacing=0 cellPadding=0 align=right>
    <tbody>
        <tr align=right>
            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"> <br>
            <table cellSpacing=0 cellPadding=0 border=0>
                <tbody>
                    <tr>
                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0> <br></td>
                        <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#main" cmimpressionsent="1"><strong><font color=#996699>回页首</font><font color=#1d58d1> </font></strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name=N101DB><font color=#1d58d1><span class=atitle>错误处理</span> </font></a></p>
<p>文件系统操作经常遇到意外的问题，Boost Filesystem Library 将使用 <code>C++</code> 异常报告运行时错误。<code>boost::filesystem_error</code> 类派生自 <code>std::runtime_error</code> 类。库中的函数使用 <code>filesystem_error</code> 异常报告操作错误。与不同的可能错误类型对应，Boost 头文件定义了相应的错误代码。用户代码通常驻留在 <code>try...catch</code> 块内，使用 <code>filesystem_error</code> 异常来报告相关错误消息。<a href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#list7" cmimpressionsent="1"><font color=#996699>清单 7</font></a> 提供了重命名文件的小示例，在 <code>from</code> 路径中的文件不存在时引发异常。 </p>
<br><a name=list7><font color=#1d58d1><strong>清单 7. Boost 中的错误处理</strong> </font></a><br>
<table cellSpacing=0 cellPadding=0 width="65%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>
            #include &lt;iostream&gt;
            #include &#8220;boost/filesystem.hpp&#8221;
            int main()
            {
            try {
            boost::filesystem::path path("C:\\src\\hdbase\\j1");
            boost::filesystem::path path2("C:\\src\\hdbase\\j2");
            boost::filesystem::rename(path, path2);
            }
            catch(boost::filesystem::filesystem_error e) {
            // do the needful
            }
            return 0;
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"> <br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0> </td>
        </tr>
    </tbody>
</table>
<table class=no-print cellSpacing=0 cellPadding=0 align=right>
    <tbody>
        <tr align=right>
            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"> <br>
            <table cellSpacing=0 cellPadding=0 border=0>
                <tbody>
                    <tr>
                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0> <br></td>
                        <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#main" cmimpressionsent="1"><strong><font color=#996699>回页首</font><font color=#1d58d1> </font></strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name=N1020D><font color=#1d58d1><span class=atitle>Boost Filesystem Library 中的函数类别</span> </font></a></p>
<p><code>boost::filesystem</code> 提供了不同类别的函数：有些函数（如 <code>is_directory</code>）用于查询文件系统，而其他函数（如 <code>create_directory</code>）则主动对文件系统进行修改。根据各自功能的不同，这些函数可以大略归入以下类别： </p>
<ul>
    <li><strong>属性函数：</strong>提供杂项信息，如文件大小、磁盘使用量等。
    <li><strong>文件系统操作函数：</strong>用于创建常规文件、目录和符号链接；复制和重命名文件；提供删除功能。
    <li><strong>实用工具：</strong>测试文件的扩展名等。
    <li><strong>杂项常规函数：</strong>以编程方式更改文件扩展名等。 </li>
</ul>
<p><a name=N1023C><span class=smalltitle><strong><font color=#1d58d1><font face=Arial>属性函数</font> </font></strong></span></a></p>
<p>Boost Filesystem Library 包括以下属性函数：</p>
<ul>
    <li><strong><code>uintmax_t file_size(const path&amp;)</code>：</strong>返回常规文件的大小（以字节为单位）
    <li><strong><code>boost::filesystem::space_info space(const path&amp;)</code>：</strong>接受路径作为输入，并返回定义如下的 <code>space_info</code> 结构：
    <table cellSpacing=0 cellPadding=0 width="50%" border=0>
        <tbody>
            <tr>
                <td class=code-outline>
                <pre class=displaycode>
                struct space_info {
                uintmax_t capacity;
                uintmax_t free;
                uintmax_t available;
                };
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br>
    <p>根据文件系统所属的磁盘分区，此流程将对该分区的所有目录返回相同的磁盘使用量统计数据（以字节为单位）。例如，对于 C:\src\dir1 和 C:\src\dir2，都会返回相同的磁盘使用数据。 </p>
    <li><strong><code>std::time_t last_write_time(const path&amp;)</code>：</strong>返回文件的最后修改时间。
    <li><strong><code>void last_write_time(const path&amp;, std::time_t new_time)</code>：</strong>修改文件的最后修改时间。
    <li><strong><code>const path&amp; current_path( )</code>：</strong>返回程序的当前工作目录的完整路径（注意，此路径与最初运行程序的路径<em>可能不同</em>，因为可能采用编程方式更改目录）。 </li>
</ul>
<p><a name=N10288><span class=smalltitle><strong><font color=#1d58d1><font face=Arial>文件系统操作函数</font> </font></strong></span></a></p>
<p>这组函数负责进行新文件和目录创建、文件删除等操作： </p>
<ul>
    <li><strong><code>bool create_directory(const path&amp;)</code>：</strong>此函数使用给定的路径名称创建目录。（请注意，如果 PATHNAME 本身包含无效字符，则结果经常是由平台定义的。例如，在 UNIX 和 Windows 系统中，星号 (<code>*</code>)、问号 (<code>?</code>) 及其他此类字符视为无效，不能出现在目录名称中。）
    <li><strong><code>bool create_directories(const path&amp;)</code>：</strong>与创建单个目录相对，您可以使用此 API 创建目录树。例如，以目录树 /a/b/c 为例，必须在 /tmp 文件夹内创建此目录树。可调用此 API 完成任务，但使用相同的参数调用 <code>create_directory</code> 时将引发异常。
    <li><strong><code>bool create_hard_link (const path&amp; frompath, const path&amp; topath)</code>：</strong>此函数在 <code>frompath</code> 和 <code>topath</code> 间创建硬链接。
    <li><strong><code>bool create_symlink(const path&amp; frompath, const path&amp; topath)</code>：</strong>此函数在 <code>frompath</code> 和 <code>topath</code> 间创建符号（软）链接。
    <li><strong><code>void copy_file(const path&amp; frompath, const path&amp; topath)</code>：</strong>将 <code>frompath</code> 引用的文件的内容和属性复制到 <code>topath</code> 引用的文件中。例程<strong>expects a destination file to be absent</strong>；如果存在目标文件，则会引发异常。因此，此函数与 UNIX 中系统指定的 <code>cp</code> 命令并不等效。另外，此函数还预期 <code>frompath</code> 变量将引用正确的常规文件。请看以下示例：<code>frompath</code> 引用符号链接 /tmp/file1，而后者反过来引用文件 /tmp/file2；而 <code>topath</code> 可以为 /tmp/file3。在这种情况下，<code>copy_file</code> 将失败。这是此 API 与 <code>cp</code> 命令相比的另一个差别。
    <li><strong><code>void rename(const path&amp; frompath, const path&amp; topath)</code>：</strong>此函数是用于重命名文件的 API。可以通过在 <code>topath</code> 参数中指定完整路径名来同时重命名和更改文件的位置，如<a href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#list8" cmimpressionsent="1"><font color=#996699>清单 8</font></a> 中所示。 <br><br><a name=list8><strong><font color=#1d58d1>清单 8. Boost 中的重命名功能</font></strong></a><br>
    <table cellSpacing=0 cellPadding=0 width="50%" border=0>
        <tbody>
            <tr>
                <td class=code-outline>
                <pre class=displaycode>
                #include &lt;stdio.h&gt;
                #include &#8220;boost/filesystem.hpp&#8221;
                int main()
                {
                boost::filesystem::path path("/home/user1/abc");
                boost::filesystem::rename(path, "/tmp/def");
                return 0;
                }
                // abc is renamed def and moved to /tmp folder
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br>
    <li><strong><code>bool remove(const path&amp; p)</code>：</strong>此例程将尝试删除路径 <em>p</em> 所引用的文件或目录。对于目录的情况，如果目录的内容不为空，则此例程将引发异常。警告：此例程<em>并不考虑所删除的内容</em>，即使其他程序在访问同一文件也如此！
    <li><strong><code>unsigned long remove_all(const path&amp; p)</code>：</strong>此 API 尝试删除路径 <em>p</em> 所引用的文件或目录。与 <code>remove</code> 不同，此函数并不会特殊考虑不为空的目录。此函数是 UNIX <code>rm &#8211;rf</code> 命令的 Boost 对等项。 </li>
</ul>
<p><a name=N10345><span class=smalltitle><strong><font color=#1d58d1><font face=Arial>实用工具</font> </font></strong></span></a></p>
<p>Boost Filesystem Library 包含以下实用工具：</p>
<ul>
    <li><strong><code>bool exists(const path&amp;)</code>：</strong>此函数检查文件的扩展名。文件可以为任何类型：常规文件、目录、符号链接等等。
    <li><strong><code>bool is_directory(const path&amp;)</code>：</strong>此函数检查路径是否与目录对应。
    <li><strong><code>bool is_regular(const path&amp;)</code>：</strong>此函数检查普通文件（即此文件不是目录、符号链接、套接字或设备文件）。
    <li><strong><code>bool is_other(const path&amp;)</code>：</strong>通常，此函数检查设备文件（如 /dev/tty0）或套接字文件。
    <li><strong><code>bool is_empty(const path&amp;)</code>：</strong>如果路径与文件夹对应，此函数将检查文件夹是否为空，并据此返回&#8220;True&#8221;或&#8220;False&#8221;。如果路径与文件对应，此函数将检查文件的大小是否等于 0。对于文件的硬链接或符号链接的情况，此 API 将检查原始文件是否为空。
    <li><strong><code>bool equivalent(const path1&amp; p1, const path2&amp; p2)</code>：</strong>此 API 非常实用，可用于比较相对路径和绝对路径名。请看<a href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#list9" cmimpressionsent="1"><font color=#996699>清单 9</font></a>： <br><br><a name=list9><strong><font color=#1d58d1>清单 9. 测试两个路径是否等效</font></strong></a><br>
    <table cellSpacing=0 cellPadding=0 width="50%" border=0>
        <tbody>
            <tr>
                <td class=code-outline>
                <pre class=displaycode>
                #include &lt;stdio.h&gt;
                #include &#8220;boost/filesystem.hpp&#8221;
                int main()
                {
                boost::filesystem::path path1("/usr/local/include"); // random pathname
                boost::filesystem::path path2("/tmp/../usr/local/include");
                bool result = boost::filesystem::is_equivalent(path1, path2);
                printf(&#8220;Paths are equivalent : %d\n&#8221;, result);
                return 0;
                }
                // result: 1
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br>
    <li><strong><code>path system_complete(const path&amp;)</code>：</strong>此函数是与 <code>bool equivalent(const path1&amp; p1, const path2&amp; p2)</code> 同一系列的另一个 API。在给定当前工作目录中任意文件路径的情况下，此 API 将返回该文件的绝对路径。例如，如果用户位于目录 /home/user1 并查询文件 ../user2/file2，此函数将返回 <code>/home/user2/file2</code>，即文件 file2 的完整路径名。 </li>
</ul>
<p><a name=N103AC><span class=smalltitle><strong><font color=#1d58d1><font face=Arial>杂项函数</font> </font></strong></span></a></p>
<p>Boost Filesystem Library 包括以下杂项函数：</p>
<ul>
    <li><strong><code>std::string extension(const path&amp;)</code>：</strong>此函数以前面带句点 (<code>.</code>) 的形式返回给定文件名的扩展名。例如，对于文件名为 <em>test.cpp</em> 的文件，<code>extension</code> 将返回 <code>.cpp</code>。对于文件没有扩展名的情况，此函数将返回空字符串。对于隐藏文件（即 UNIX 系统中文件名以 <code>.</code> 开始的文件），此函数将相应地计算扩展名类型或返回空字符串（因此，对于 <em>.test.profile</em>，此例程将返回 <code>.profile</code>）。
    <li><strong><code>std::string basename(const path&amp;)</code>：</strong>这是与 <code>extension</code> 互补的例程。它将返回文件名中 <code>.</code> 之前的字符串。请注意，即使提供了绝对文件名，此 API 仍然仅会返回属于文件名的直接部分，如<a href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#list10" cmimpressionsent="1"><font color=#996699>清单 10</font></a> 中所示。 <br><br><a name=list10><strong><font color=#1d58d1>清单 10. 使用 boost::basename</font></strong></a><br>
    <table cellSpacing=0 cellPadding=0 width="50%" border=0>
        <tbody>
            <tr>
                <td class=code-outline>
                <pre class=displaycode>
                #include &lt;stdio.h&gt;
                #include &lt;cstring&gt;
                #include &#8220;boost/filesystem.hpp&#8221;
                use namespace std;
                int main()
                {
                boost::filesystem::path path1("/tmp/dir1/test1.c ");
                boost::filesystem::path path2("/tmp/dir1/.test1.profile");
                string result1 = boost::filesystem::basename (path1);
                string result2 = boost::filesystem::basename (path2);
                printf(&#8220;Basename 1: %s  Basename2 : %s\n&#8221;, result1.c_str(), result2.c_str());
                return 0;
                }
                // result: Basename1: test1 Basename2: .test1
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br>
    <li><strong><code>std::string change_extension(const path&amp; oldpath, const std::string new_extension)</code>：</strong>此 API 将返回反映更改后的名称的新字符串。请注意，与 <code>oldpath</code> 对应的文件保持<strong>不变</strong>。这只是一个常规函数。另请注意，您必须显式地在扩展名中指定<em>点</em>。例如，<code>change_extension("test.c", "so")</code> 会得到 <code>testso</code>，而不是 <code>test.so</code>。 </li>
</ul>
<br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"> <br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0> </td>
        </tr>
    </tbody>
</table>
<table class=no-print cellSpacing=0 cellPadding=0 align=right>
    <tbody>
        <tr align=right>
            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"> <br>
            <table cellSpacing=0 cellPadding=0 border=0>
                <tbody>
                    <tr>
                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0> <br></td>
                        <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#main" cmimpressionsent="1"><strong><font color=#996699>回页首</font><font color=#1d58d1> </font></strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name=N1041B><font color=#1d58d1><span class=atitle>结束语</span> </font></a></p>
<p>本文提供了 Boost Filesystem Library 的简单概述。不应将本文视为 Boost 中的整个文件系统接口的综合文档。并未讨论此 API 集的内部情况，也没有讨论这些 API 在非 UNIX 或 Windows 平台（如 VMS）中的细节。有关文件系统的更多信息，请参见<a href="http://www.ibm.com/developerworks/cn/aix/library/au-boostfs/#resources" cmimpressionsent="1"><font color=#996699>参考资料</font></a>。 </p>
<br><br>
<p><a name=resources><span class=atitle><font color=#1d58d1>参考资料 </font></span></a></p>
<strong>学习</strong> <br>
<ul>
    <li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/aix/library/au-boostfs/?S_CMP=cn-a-aix&amp;S_TACT=105AGX52" target=_blank cmimpressionsent="1"><font color=#5c81a7>英文原文</font></a> 。<br><br>
    <li><a href="http://www.boost.org/libs/filesystem/doc/index.htm" cmimpressionsent="1"><font color=#5c81a7>Boost Filesystem Library 文档</font><font color=#1d58d1> </font></a>：阅读 Boost Filesystem Library 文档（相对而言，更加适合开发人员，而不是普通用户）。<br><br>
    <li><a href="http://beans.seartipy.com/2006/05/10/boost-filesystem-library-writing-portable-c-programs-to-acess-the-filesystem/" cmimpressionsent="1"><font color=#5c81a7>Every Flavour Beans</font><font color=#1d58d1> </font></a>：这篇文章对 Boost Filesystem Library 非常独到的介绍，提供了安装 Boost 库的详细信息。<br><br>
    <li><a href="http://solarix.ru/for_developers/cpp/boost/filesystem/en/index.shtml" cmimpressionsent="1"><font color=#5c81a7>Detailed Filesystem Library 文档</font><font color=#1d58d1> </font></a>：查找关于 PATHNAME 检查函数的信息。<br><br>
    <li><a href="http://www.ibm.com/developerworks/cn/aix" cmimpressionsent="1"><font color=#5c81a7>AIX and UNIX 专区</font><font color=#1d58d1> </font></a>：developerWorks 的&#8220;AIX and UNIX 专区&#8221;提供了大量与 AIX 系统管理的所有方面相关的信息，您可以利用它们来扩展自己的 UNIX 技能。<br><br>
    <li><a href="http://www.ibm.com/developerworks/cn/aix/newto" cmimpressionsent="1"><font color=#5c81a7>AIX and UNIX 新手入门</font><font color=#1d58d1> </font></a>：访问&#8220;AIX and UNIX 新手入门&#8221;页面可了解更多关于 AIX 和 UNIX 的内容。<br><br>
    <li><a href="http://www.ibm.com/developerworks/cn/aix/lpsummary.html" cmimpressionsent="1"><font color=#5c81a7>AIX and UNIX 专题汇总</font><font color=#1d58d1> </font></a>：AIX and UNIX 专区已经为您推出了很多的技术专题，为您总结了很多热门的知识点。我们在后面还会继续推出很多相关的热门专题给您，为了方便您的访问，我们在这里为你把本专区的所有专题进行汇总，让您更方便的找到你需要的内容。<br><br>
    <li><a href="http://www.ibm.com/developerworks/cn/offers/techbriefings" cmimpressionsent="1"><font color=#5c81a7>developerWorks 技术事件和网络广播</font><font color=#1d58d1> </font></a>：了解最新的 developerWorks 技术事件和网络广播。<br><br>
    <li><a href="http://www-941.ibm.com/collaboration/wiki/display/WikiPtype/Home" cmimpressionsent="1"><font color=#5c81a7>AIX Wiki</font><font color=#1d58d1> </font></a>：访问这个与 AIX 相关的技术信息协作环境。<br><br>
    <li><a href="http://www-128.ibm.com/developerworks/podcast/" cmimpressionsent="1"><font color=#5c81a7>Podcast</font><font color=#1d58d1> </font></a>：收听 Podcast 并与 IBM 技术专家保持同步。<br></li>
</ul>
<img src ="http://www.cppblog.com/deadpunk/aggbug/67670.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deadpunk/" target="_blank">活着就是折腾，所以当然要骠悍的折腾</a> 2008-11-23 16:31 <a href="http://www.cppblog.com/deadpunk/archive/2008/11/23/67670.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转载)你是我的玫瑰-类关系阐微</title><link>http://www.cppblog.com/deadpunk/archive/2008/06/18/53811.html</link><dc:creator>活着就是折腾，所以当然要骠悍的折腾</dc:creator><author>活着就是折腾，所以当然要骠悍的折腾</author><pubDate>Wed, 18 Jun 2008 01:59:00 GMT</pubDate><guid>http://www.cppblog.com/deadpunk/archive/2008/06/18/53811.html</guid><wfw:comment>http://www.cppblog.com/deadpunk/comments/53811.html</wfw:comment><comments>http://www.cppblog.com/deadpunk/archive/2008/06/18/53811.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deadpunk/comments/commentRss/53811.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deadpunk/services/trackbacks/53811.html</trackback:ping><description><![CDATA[<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 原帖地址：http://www.cnblogs.com/zjzkiss/<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 世界是普遍联系的，因此程序世界中的类，也不可能是孤立的。</span><span>UML</span><span>为我们定义了它们之间的关系，就是：依赖、关联、聚合、组合还有泛化。</span>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>泛化关系比较好理解，就是表示类之间的继承关系。容易混淆的是依赖、关联、聚合和组合的关系。这里做一些甄别：</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、&nbsp;</span></span><span>依赖和关联的颠倒颠</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在网上查找了一下依赖和关联的区别，有说&#8220;</span><span>关联本身即是一种依赖&#8221;，亦有说&#8220;</span><span>依赖是一种弱关联</span><span>&#8221;，其实说来说去是一档子事。依赖和关联都是说一个类用到了另一个类。其区别在于一个是使用，一个是拥有。</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>依赖</strong>：具有某种偶然性。比如说我要过河，没有桥怎么办，我就去借来一条小船渡过去。我与小船的关系仅仅是使用（借用）的关系。表现在代码上，为依赖的类的某个方法以被依赖的类作为其参数。或者是</span><span>class A </span><span>的某个方法创造了</span><span> class B </span><span>的实例抑或对</span><span>class B</span><span>的</span><span>静态方法的调用</span><span>。如果</span><span>A</span><span>依赖于</span><span>B</span><span>，那意味着</span><span>B</span><span>的变化可能要求</span><span>A</span><span>也发生变化；</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这是</span><span>uml</span><span>图表示的依赖关系：<br><span style="font-size: 10.5pt; font-family: 'times new roman';" lang="EN-US"><v:shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img  src="http://www.cnblogs.com/images/cnblogs_com/zjzkiss/l5.GIF" alt="" border="0" width="274" height="101"><br><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></v:path><o:lock aspectratio="t" v:ext="edit"><span style="font-size: 10.5pt; font-family: 宋体;">代码表现：<br></span></o:lock></v:shapetype></span></span></p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><span style="color: #008080;">1</span><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" id="Codehighlighter1_19_116_Open_Image" onclick="this.style.display='none'; codehighlighter1_19_116_open_text.style.display="'none';" codehighlighter1_19_116_closed_image.style.display="'inline';" codehighlighter1_19_116_closed_text.style.display="'inline';"" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" id="Codehighlighter1_19_116_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_19_116_closed_text.style.display="'none';" codehighlighter1_19_116_open_image.style.display="'inline';" codehighlighter1_19_116_open_text.style.display="'inline';"" align="top"><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Person</span><span id="Codehighlighter1_19_116_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif"></span><span id="Codehighlighter1_19_116_Open_Text"><span style="color: #000000;">{&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">2</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" id="Codehighlighter1_29_37_Open_Image" onclick="this.style.display='none'; codehighlighter1_29_37_open_text.style.display="'none';" codehighlighter1_29_37_closed_image.style.display="'inline';" codehighlighter1_29_37_closed_text.style.display="'inline';"" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" id="Codehighlighter1_29_37_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_29_37_closed_text.style.display="'none';" codehighlighter1_29_37_open_image.style.display="'inline';" codehighlighter1_29_37_open_text.style.display="'inline';"" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_29_37_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;">/**/</span><span id="Codehighlighter1_29_37_Open_Text"><span style="color: #008000;">/*</span><span style="color: #008000;">*&nbsp;划船&nbsp;</span><span style="color: #008000;">*/</span></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">3</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" id="Codehighlighter1_76_110_Open_Image" onclick="this.style.display='none'; codehighlighter1_76_110_open_text.style.display="'none';" codehighlighter1_76_110_closed_image.style.display="'inline';" codehighlighter1_76_110_closed_text.style.display="'inline';"" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" id="Codehighlighter1_76_110_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_76_110_closed_text.style.display="'none';" codehighlighter1_76_110_open_image.style.display="'inline';" codehighlighter1_76_110_open_text.style.display="'inline';"" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;oarage&nbsp;(Boat&nbsp;boat)</span><span id="Codehighlighter1_76_110_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif"></span><span id="Codehighlighter1_76_110_Open_Text"><span style="color: #000000;">{&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">4</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boat.oarage();&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">5</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;}</span></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">6</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top">}</span></span><span style="color: #000000;">&nbsp;<br></span><span style="color: #008080;">7</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"></span></div>
<br>&nbsp;
<p><strong><span>关联：有名的客户和订单的关系以及公司和员工的关系，都是关联关系。还有就是我和我的单车的例子，他们都是一种&#8220;拥有&#8221;的关系。表现在代码上，就是一个类包含另一个类的实例，</span></strong><span>通常表现为被关联类以类属性的形式出现在关联类的类定义中，也可以表现为关联类引用了一个类型为被关联类的全局变量。关联可以使单向的，也可以使双向的。</span></p>
<p><span>从网上找到的公司和员工的<span>UML</span>图和代码 ：</span></p>
<img  src="http://www.cnblogs.com/images/cnblogs_com/zjzkiss/l2.GIF" alt="" border="0" width="303" height="74"><br><span style="font-size: 10pt; font-family: 宋体;"><strong>公司和员工的关联关系<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><span style="color: #008080;">&nbsp;1</span><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" id="Codehighlighter1_20_326_Open_Image" onclick="this.style.display='none'; codehighlighter1_20_326_open_text.style.display="'none';" codehighlighter1_20_326_closed_image.style.display="'inline';" codehighlighter1_20_326_closed_text.style.display="'inline';"" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" id="Codehighlighter1_20_326_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_20_326_closed_text.style.display="'none';" codehighlighter1_20_326_open_image.style.display="'inline';" codehighlighter1_20_326_open_text.style.display="'inline';"" align="top"><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Company</span><span id="Codehighlighter1_20_326_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif"></span><span id="Codehighlighter1_20_326_Open_Text"><span style="color: #000000;">{&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;2</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Employee&nbsp;employee;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;3</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" id="Codehighlighter1_94_133_Open_Image" onclick="this.style.display='none'; codehighlighter1_94_133_open_text.style.display="'none';" codehighlighter1_94_133_closed_image.style.display="'inline';" codehighlighter1_94_133_closed_text.style.display="'inline';"" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" id="Codehighlighter1_94_133_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_94_133_closed_text.style.display="'none';" codehighlighter1_94_133_open_image.style.display="'inline';" codehighlighter1_94_133_open_text.style.display="'inline';"" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Employee&nbsp;getEmployee()</span><span id="Codehighlighter1_94_133_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif"></span><span id="Codehighlighter1_94_133_Open_Text"><span style="color: #000000;">{&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;4</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;employee;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;5</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;6</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" id="Codehighlighter1_185_231_Open_Image" onclick="this.style.display='none'; codehighlighter1_185_231_open_text.style.display="'none';" codehighlighter1_185_231_closed_image.style.display="'inline';" codehighlighter1_185_231_closed_text.style.display="'inline';"" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" id="Codehighlighter1_185_231_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_185_231_closed_text.style.display="'none';" codehighlighter1_185_231_open_image.style.display="'inline';" codehighlighter1_185_231_open_text.style.display="'inline';"" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;setEmployee(Employee&nbsp;employee)</span><span id="Codehighlighter1_185_231_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif"></span><span id="Codehighlighter1_185_231_Open_Text"><span style="color: #000000;">{&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;7</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.employee</span><span style="color: #000000;">=</span><span style="color: #000000;">employee;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;8</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;9</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">公司运作&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #008080;">10</span><span style="color: #008000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" id="Codehighlighter1_273_320_Open_Image" onclick="this.style.display='none'; codehighlighter1_273_320_open_text.style.display="'none';" codehighlighter1_273_320_closed_image.style.display="'inline';" codehighlighter1_273_320_closed_text.style.display="'inline';"" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" id="Codehighlighter1_273_320_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_273_320_closed_text.style.display="'none';" codehighlighter1_273_320_open_image.style.display="'inline';" codehighlighter1_273_320_open_text.style.display="'inline';"" align="top"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;run()</span><span id="Codehighlighter1_273_320_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif"></span><span id="Codehighlighter1_273_320_Open_Text"><span style="color: #000000;">{&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">11</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;employee.startWorking();&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">12</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">13</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top">}</span></span><span style="color: #000000;">&nbsp;&nbsp;<br></span><span style="color: #008080;">14</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"></span></div>
</strong></span><br>&nbsp;
<p><span>可见依赖于与关联亦有动静之别，</span><span>关联的类<span>&#8220;</span>静态<span>&#8221;</span>地引用了被关联类的实例变量，而依赖的偶然性也正说明了它的动态性。</span><strong></strong></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、&nbsp;</span></span><span>聚合与组合同出而异体</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;聚合与组合其实都是关联的特例，都是整体和部分的关系。他们的区别在于聚合的两个对象之间是可分离的，他们具有各自的生命周期。而组合往往表现为一种唇齿相依的关系。</span></p>
<p><span>聚合：一种容纳或曰包含的关系，如同机场和飞机，汽车和轮胎的关系。其实仔细想想，前面的公司和员工的关系也有聚合的味道在里面。</span></p>
<p><span>组合：也可称之为强聚合，整体和部分是不可分的，整体的生命周期结束时也就是部分的生命周期到头时。很有名的就是桌子和桌子腿的关系。</span></p>
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;聚合的</span><span>UML</span><span>图</span>：<br><img  src="http://www.cnblogs.com/images/cnblogs_com/zjzkiss/l3.GIF" alt="" border="0" width="245" height="90"><br>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 21pt; text-indent: 18pt;"><span style="font-family: 宋体;">组合的</span><span lang="EN-US"><font face="Times New Roman">UML</font></span><span style="font-family: 宋体;">图：</span></p>
<br><br><img  src="http://www.cnblogs.com/images/cnblogs_com/zjzkiss/l4.GIF" alt="" border="0" width="245" height="90"><br>&nbsp;
<p><span>然而，聚合与组合的代码表现形式是一样的，都可以表现为以下的形式，它们仅仅具有语义上的区别。</span></p>
<p><span>网上找到的电脑和</span><span>CPU</span><span>的关系的代码表现：</span></p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><span style="color: #008080;">&nbsp;1</span><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" id="Codehighlighter1_21_285_Open_Image" onclick="this.style.display='none'; codehighlighter1_21_285_open_text.style.display="'none';" codehighlighter1_21_285_closed_image.style.display="'inline';" codehighlighter1_21_285_closed_text.style.display="'inline';"" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" id="Codehighlighter1_21_285_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_21_285_closed_text.style.display="'none';" codehighlighter1_21_285_open_image.style.display="'inline';" codehighlighter1_21_285_open_text.style.display="'inline';"" align="top"><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Computer</span><span id="Codehighlighter1_21_285_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif"></span><span id="Codehighlighter1_21_285_Open_Text"><span style="color: #000000;">{&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;2</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;CPU&nbsp;cpu;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;3</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" id="Codehighlighter1_75_109_Open_Image" onclick="this.style.display='none'; codehighlighter1_75_109_open_text.style.display="'none';" codehighlighter1_75_109_closed_image.style.display="'inline';" codehighlighter1_75_109_closed_text.style.display="'inline';"" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" id="Codehighlighter1_75_109_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_75_109_closed_text.style.display="'none';" codehighlighter1_75_109_open_image.style.display="'inline';" codehighlighter1_75_109_open_text.style.display="'inline';"" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;CPU&nbsp;getCPU()</span><span id="Codehighlighter1_75_109_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif"></span><span id="Codehighlighter1_75_109_Open_Text"><span style="color: #000000;">{&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;4</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;cpu;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;5</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;6</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" id="Codehighlighter1_146_182_Open_Image" onclick="this.style.display='none'; codehighlighter1_146_182_open_text.style.display="'none';" codehighlighter1_146_182_closed_image.style.display="'inline';" codehighlighter1_146_182_closed_text.style.display="'inline';"" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" id="Codehighlighter1_146_182_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_146_182_closed_text.style.display="'none';" codehighlighter1_146_182_open_image.style.display="'inline';" codehighlighter1_146_182_open_text.style.display="'inline';"" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;setCPU(CPU&nbsp;cpu)</span><span id="Codehighlighter1_146_182_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif"></span><span id="Codehighlighter1_146_182_Open_Text"><span style="color: #000000;">{&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;7</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.cpu</span><span style="color: #000000;">=</span><span style="color: #000000;">cpu;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;8</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;9</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">开启电脑&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #008080;">10</span><span style="color: #008000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" id="Codehighlighter1_226_279_Open_Image" onclick="this.style.display='none'; codehighlighter1_226_279_open_text.style.display="'none';" codehighlighter1_226_279_closed_image.style.display="'inline';" codehighlighter1_226_279_closed_text.style.display="'inline';"" align="top"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" id="Codehighlighter1_226_279_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_226_279_closed_text.style.display="'none';" codehighlighter1_226_279_open_image.style.display="'inline';" codehighlighter1_226_279_open_text.style.display="'inline';"" align="top"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;start()</span><span id="Codehighlighter1_226_279_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img  src="http://www.cnblogs.com/Images/dot.gif"></span><span id="Codehighlighter1_226_279_Open_Text"><span style="color: #000000;">{&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">11</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">cpu运作&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #008080;">12</span><span style="color: #008000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align="top"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cpu.run();&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">13</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">14</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top">}</span></span><span style="color: #000000;">&nbsp;&nbsp;<br></span><span style="color: #008080;">15</span><span style="color: #000000;"><img  src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"></span></div>
<br>&nbsp;
<p><span>&nbsp;&nbsp;&nbsp;结语：</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一般情况下，当某个类被当作参数传递并且被当作结果返回的时候，或者被当作某个方法内的临时变量使用的时候</span><span>,</span><span>可以运用依赖关系，使用关联来表示一个拥有关系，而不是整体</span><span>-</span><span>部分关系。使用聚合来表示一个动态的整体</span><span>-</span><span>部分关系，而是用组合来表示一个静态的整体</span><span>-</span><span>部
分关系。但是需要指出的是，所谓&#8220;关系&#8221;只是在某个问题域才有效，离开了这个问题域，可能这些关系就不成立了，例如之前我和小船的关系，可能在某个问题域
中，我是船夫，我的工作就是驾着小船在河上摆渡，那我和小船的关系就上升为关联关系了。试想一下，武侠小说中的那些剑仙们，修炼到人剑合一的境地，剑在人
在，剑亡人亡，那它们之间的关系就似乎与组合关系类似了。又如在关心汽车的领域里，轮胎是一定要组合在汽车类中的，因为它离开了汽车就没有意义了。但是在
卖轮胎的店铺业务里，就算轮胎离开了汽车，它也是有意义的，这就可以用聚合了。这说明关系是在特定的问题域中的&#8220;关系&#8221;，会随着问题域的迁移而改变的。最
后顺便问一句：老公和老婆的关系是依赖还是关联呢？一笑</span><span>&#8230;&#8230;</span></p><img src ="http://www.cppblog.com/deadpunk/aggbug/53811.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deadpunk/" target="_blank">活着就是折腾，所以当然要骠悍的折腾</a> 2008-06-18 09:59 <a href="http://www.cppblog.com/deadpunk/archive/2008/06/18/53811.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转载)关于ACE_InputCDR和ACE_OutputCDR读写数据时的经验</title><link>http://www.cppblog.com/deadpunk/archive/2008/03/19/44858.html</link><dc:creator>活着就是折腾，所以当然要骠悍的折腾</dc:creator><author>活着就是折腾，所以当然要骠悍的折腾</author><pubDate>Wed, 19 Mar 2008 07:44:00 GMT</pubDate><guid>http://www.cppblog.com/deadpunk/archive/2008/03/19/44858.html</guid><wfw:comment>http://www.cppblog.com/deadpunk/comments/44858.html</wfw:comment><comments>http://www.cppblog.com/deadpunk/archive/2008/03/19/44858.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deadpunk/comments/commentRss/44858.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deadpunk/services/trackbacks/44858.html</trackback:ping><description><![CDATA[<p><font size=3><font face=宋体>我今天测试发现</font><font face=Arial>ACE_InputCDR</font><font face=宋体>和</font><font face=Arial>ACE_OutputCDR</font><font face=宋体>并不是那么简单。</font><font face=Arial><o:p></o:p></font></font></p>
<p><font face=宋体 size=3>如果稍微不注意就会出现一些奇怪的字节错位的情况。</font><font face=Arial><o:p></o:p></font></p>
<p><font face=Arial size=3><o:p></o:p></font></p>
<p><font face=宋体 size=3>在这里我总结一下使用的规则：</font><font face=Arial><o:p></o:p></font></p>
<p><font face=Arial size=3><o:p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ACE_OutputCDR out(mb);</o:p></font></p>
<p><font face=Arial size=3><o:p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out&nbsp;&nbsp;&lt;&lt; ?? ;&nbsp;&nbsp;&nbsp;&nbsp; //这种方法简称out</o:p></font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>例一：</font><font face=Arial><o:p></o:p></font></font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>如果</font><font face=Arial>out </font><font face=宋体>了一个</font><font face=Arial>short</font><font face=宋体>再</font><font face=Arial>out</font><font face=宋体>一个</font><font face=Arial>long </font></font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>字节将成为如下排列</font><font face=Arial>(16</font><font face=宋体>进制</font><font face=Arial>)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xx xx ?? ?? xx xx xx xx<o:p></o:p></font></font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>其中，问号部分即是因为在</font><font face=Arial>long</font><font face=宋体>写入时进行的按</font><font face=Arial>long</font><font face=宋体>长度对齐。该数据是无意义的</font><font face=Arial><o:p></o:p></font></font></p>
<p><font face=Arial><font size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <o:p></o:p></font></font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>例二：</font><font face=Arial><o:p></o:p></font></font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>如果</font><font face=Arial>out</font><font face=宋体>了一个</font><font face=Arial>char</font><font face=宋体>再</font><font face=Arial>out</font><font face=宋体>一个</font><font face=Arial> short<o:p></o:p></font></font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>字节将成为如下排列</font><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xx&nbsp;&nbsp;??&nbsp;&nbsp;xx xx<o:p></o:p></font></font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>其中，问号部分即是因为在</font><font face=Arial>short</font><font face=宋体>写入时进行的按</font><font face=Arial>short</font><font face=宋体>长度对齐。该数据是无意义的</font><font face=Arial><o:p></o:p></font></font></p>
<p><font face=Arial><font size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <o:p></o:p></font></font></p>
<p><font face=Arial><font size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <o:p></o:p></font></font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>例三：</font><font face=Arial><o:p></o:p></font></font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>如果</font><font face=Arial>out</font><font face=宋体>了一个</font><font face=Arial>short</font><font face=宋体>再</font><font face=Arial>out</font><font face=宋体>一个</font><font face=Arial>char<o:p></o:p></font></font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>字节将成为如下排列</font><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xx&nbsp;&nbsp;xx&nbsp;&nbsp;&nbsp;&nbsp;xx <o:p></o:p></font></font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>这里输入的</font><font face=Arial>char</font><font face=宋体>不会造成对齐问题，因为</font><font face=Arial>char</font><font face=宋体>只有一个字节（都是倍数）</font><font face=Arial><o:p></o:p></font></font></p>
<p><font face=Arial><font size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <o:p></o:p></font></font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>例四：</font><font face=Arial><o:p></o:p></font></font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>如果</font><font face=Arial>out</font><font face=宋体>了一个</font><font face=Arial>short</font><font face=宋体>再</font><font face=Arial>out</font><font face=宋体>一个</font><font face=Arial>char </font><font face=宋体>再</font><font face=Arial>out </font><font face=宋体>一个</font><font face=Arial> long<o:p></o:p></font></font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>字节将成为如下排列</font><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xx&nbsp;&nbsp;xx&nbsp;&nbsp;xx&nbsp;&nbsp;??&nbsp;&nbsp;xx&nbsp;&nbsp;xx&nbsp;&nbsp;xx&nbsp;&nbsp;xx<o:p></o:p></font></font></p>
<p><font face=Arial><font size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <o:p></o:p></font></font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>按照以上可总结出，每</font><font face=Arial>out</font><font face=宋体>一个类型的数据时，输出流将自动按照这个输入类型的长度序对齐，如果没有对齐，则自动填充。</font></font></p>
<p><font face=宋体 size=3>&nbsp;&nbsp;&nbsp;&nbsp; 导致读数据时产生非常多的问题。（你不见CNPV1中都是强转成ACE_CDR::ULong吗？这下知道了吧）。</font></p>
<p><font face=宋体 size=3>解决方案有两种：</font></p>
<p><font face=宋体 size=3>方案一：全部一种类型吧！比如全部用ACE_CDR::ULong</font></p>
<p><font face=宋体 size=3>&nbsp;&nbsp;&nbsp;&nbsp;不过这种方法通常不适合实际的应用。让偶动物园墙垮来帮大家解决这个心结。:) 西西，请看下一方案。</font></p>
<p><font face=宋体 size=3>方案二：</font></p>
<p><font face=宋体 size=3>大家都会觉得这玩意被做出来怎么就不好用呢？没道理吧。我也觉得没道理，所以为了证实ACE开发者都是大牛，偶就把ACE的代码挖出来给大家看看，</font></p>
<p><font face=宋体 size=3>看看这里到底有着什么样的玄机？</font></p>
<p><font face=宋体 size=3>我们就拿ACE_ULong来开刀：</font></p>
<p><font face=宋体 size=3>大家翻开CDR_Stream.inl文件，找到以下语句</font></p>
<p><font face=宋体 size=3>ACE_INLINE ACE_CDR::Boolean<br>operator&lt;&lt; (ACE_OutputCDR &amp;os, ACE_CDR::ULong x)<br>{<br>&nbsp;&nbsp;os.write_ulong (x);<br>&nbsp;&nbsp;return (ACE_CDR::Boolean) os.good_bit ();<br>}</font></p>
<p><font face=宋体 size=3>继续下去 os.write_ulong (x);<br></font></p>
<p><font face=宋体 size=3>ACE_INLINE ACE_CDR::Boolean<br>ACE_OutputCDR::write_ulong (ACE_CDR::ULong x)<br>{<br>&nbsp;&nbsp;const void *temp = &amp;x;<br>&nbsp;&nbsp;return this-&gt;write_4 (reinterpret_cast&lt;const ACE_CDR::ULong*&gt; (temp));<br>}</font></p>
<p><font face=宋体 size=3>继续跟踪this-&gt;write_4 (reinterpret_cast&lt;const ACE_CDR::ULong*&gt; (temp));</font></p>
<p><font face=宋体 size=3>ACE_CDR::Boolean<br>ACE_OutputCDR::write_4 (const ACE_CDR::ULong *x)<br>{<br>&nbsp;&nbsp;char *buf = 0;<br>&nbsp;&nbsp;if (this-&gt;adjust (ACE_CDR::LONG_SIZE, buf) == 0)<br>&nbsp;&nbsp;&nbsp;&nbsp;{</font></p>
<p><font face=宋体 size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ....</font></p>
<p><font face=宋体 size=3>&nbsp;&nbsp;&nbsp;&nbsp;}</font></p>
<p><font face=宋体 size=3>}</font></p>
<p><font face=宋体 size=3>再继续adjust (ACE_CDR::LONG_SIZE, buf)</font></p>
<p><font face=宋体 size=3>ACE_INLINE int<br>ACE_OutputCDR::adjust (size_t size, char*&amp; buf)<br>{<br>&nbsp;&nbsp;return this-&gt;adjust (size, size, buf);<br>}</font></p>
<p><font face=宋体 size=3>继续 this-&gt;adjust (size, size, buf);</font></p>
<p><font face=宋体 size=3>ACE_INLINE int<br>ACE_OutputCDR::adjust (size_t size,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size_t align,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char*&amp; buf)<br>{<br>&nbsp;&nbsp;if (!this-&gt;current_is_writable_)<br>&nbsp;&nbsp;&nbsp;&nbsp;return this-&gt;grow_and_adjust (size, align, buf);</font></p>
<p><font face=宋体 size=3>#if !defined (ACE_LACKS_CDR_ALIGNMENT)<br>&nbsp;&nbsp;const size_t offset =<br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_align_binary (this-&gt;current_alignment_, align)<br>&nbsp;&nbsp;&nbsp;&nbsp;- this-&gt;current_alignment_;</font></p>
<p><font face=宋体 size=3>&nbsp;&nbsp;buf = this-&gt;current_-&gt;wr_ptr () + offset;<br>#else<br>&nbsp;&nbsp;buf = this-&gt;current_-&gt;wr_ptr ();<br>#endif /* ACE_LACKS_CDR_ALIGNMENT */</font></p>
<p><font face=宋体 size=3>&nbsp;&nbsp;char *end = buf + size;</font></p>
<p><font face=宋体 size=3>&nbsp;&nbsp;if (end &lt;= this-&gt;current_-&gt;end () &amp;&amp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end &gt;= buf)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>#if !defined (ACE_LACKS_CDR_ALIGNMENT)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this-&gt;current_alignment_ += offset + size;<br>#endif /* ACE_LACKS_CDR_ALIGNMENT */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this-&gt;current_-&gt;wr_ptr (end);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;}</font></p>
<p><font face=宋体 size=3>&nbsp;&nbsp;return this-&gt;grow_and_adjust (size, align, buf);<br>}</font></p>
<p><font face=宋体 size=3>好！我们找到了，原来校正的代码就在这里！仔细看看</font></p>
<p><font face=宋体 size=3>#if !defined (ACE_LACKS_CDR_ALIGNMENT)</font></p>
<p><font face=宋体 size=3>这里说明，如果你定义了ACE_LACKS_CDR_ALIGNMENT，那么ACE就不会帮你校准对齐字节啦！</font></p>
<p><font face=宋体 size=3>哈哈，是不是很兴奋？别着急，让我们动手</font></p>
<p><font face=宋体 size=3>打开config.h文件，加入以下一句</font></p>
<p><font face=宋体 size=3>#define ACE_LACKS_CDR_ALIGNMENT</font></p>
<p><font face=宋体 size=3>重新编译ACE，好，将新的lib加入工程</font></p>
<p><font face=宋体 size=3>（如果你用了aced.dll或ace.dll，注意路径，或把新的dll拷贝到system32目录下）</font></p>
<p><font face=Arial size=3><o:p>让我们来运行一下原来的程序</o:p></font></p>
<font face=Arial><o:p></o:p>
<p><font face=Arial size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out &lt;&lt; (ACE_CDR::UShort)1;</font></p>
<p><font face=Arial size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out &lt;&lt; (ACE_CDR::Long)2;</font></p>
<p><font face=Arial size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ACE_LOG_MSG-&gt;log_hexdump( LM_DEBUG , mb-&gt;base() , out.length() , "t");</font></p>
<p><font size=3><font face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face=宋体>字节将成为如下排列</font><font face=Arial>(16</font><font face=宋体>进制</font><font face=Arial>)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=#ff3300>xx xx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xx xx xx xx</font></font></font></p>
<p><font face=Arial><font color=#000000 size=3><o:p></o:p></font></font></p>
<p><font face=Arial><font color=#000000 size=3><o:p>哈哈！你再试试以上四个例子，会发现都没有问题了！</o:p></font></font></p>
<p><font face=Arial><font color=#000000 size=3><o:p></o:p></font></font></p>
</font>
<p><font face=Arial size=3><o:p>那么，从现在开始，你还需要写自己的整编和解编的包装类吗？我看没有必要了吧。还不快动手修改你的工程？ <br></o:p></font></p>
<p>补充：</p>
<p>如果不这么做。那么在接收端用ACE_IntputCDR进行 &gt;&gt; 操作时。如果没有进行读时的强制转换</p>
<p>比如 没有这样写</p>
<p>ACE_CDR::Char c;</p>
<p>ACE_CDR::UShort s;</p>
<p>ACE_InputCDR in(...);</p>
<p>in &gt;&gt; (ACE_CDR::ULong)c;</p>
<p>in &gt;&gt; (ACE_CDR::ULong)s;</p>
<p>而是这样写：</p>
<p>ACE_InputCDR in(...);</p>
<p>in &gt;&gt;&nbsp;&nbsp;c;</p>
<p>in &gt;&gt; s;</p>
<p>必出各种字节乱码问题。因为中间多了CORBA的marshaling 与demarshaling对齐数据。</p>
<p>如果按照以上方法重新编译ACE后。即可省事多了（同时也节省了网络流量）</p>
<p>ACE_OutputCDR out(..);</p>
<p>out &lt;&lt; c;</p>
<p>out &lt;&lt; s;</p>
<p>------------------------------------</p>
<p>ACE_InputCDR in(...);</p>
<p>in &gt;&gt;&nbsp;&nbsp;c;</p>
<p>in &gt;&gt; s;</p>
<p>无须任何类型转换。绝不出错。</p>
<p>再次声明。你不必自己写整编和解编。该论坛多次讨论过该问题。这是一个非常好的解决之道。</p>
<p><font face=Arial size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out &lt;&lt; (ACE_CDR::UShort)1;</font></p>
<p><font face=Arial size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out &lt;&lt; (ACE_CDR::Long)2;</font></p>
<br>
<p><font face=Arial size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ACE_LOG_MSG-&gt;log_hexdump( LM_DEBUG , mb-&gt;base() , out.length() , "t");</font><img height=21 alt="" src="http://blog.csdn.net/ruixj/archive/2008/02/21/skins/Default/toolbar/universalkey.gif" width=21></p>
<br>
<p>&nbsp;</p>
<br>
<p>&nbsp;</p>
<br>
<p>&nbsp;</p>
<p>书中第四章中有一段代码用到了ACE_CDR的"opertaor&gt; &gt; ()"提取操作符，对此有些疑问。 <br><br>代码大致如下 <br><br></p>
<dl class=code>
<dt>C/C++ code
<dd>
<pre>
<div><!--code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--><span style="COLOR: rgb(0,0,0)">ACE_InputCDR cdr(payload);  </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">payload 是一个ACE_Message_Block</span><span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,0,0)"><br>ACE_CDR::Boolean byte_roder; </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">字节顺序标志<br></span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">Use helper method to disambiguate booleams from chars</span><span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,0,0)">cdr </span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)"> ACE_InputCDR::to_boolean(Byte_order);  </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">[color=#FF0000]puzzle1[/color]</span><span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,0,0)">cdr.reset_byte_order(byte_order);             </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">[color=#FF0000]puzzle2[/color]<br><br></span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">提取payload的长度</span><span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,0,0)">ACE_CDR::Ulong length;<br>cdr </span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)"> length;     </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">[color=#FF0000]puzzle3</span></div>
<br></pre>
</dd></dl>[/color] <br><br><br>对上面的几行代码主要有2个疑问。 <br>问题一、puzzle1和puzzle3处 <br>cdr &nbsp; &gt; &gt; &nbsp; ACE_InputCDR::to_boolean(Byte_order); &nbsp; &nbsp; <br>cdr &nbsp; &gt; &gt; &nbsp; length; <br>这两个地方，cdr直接通过 &nbsp; &gt; &gt; &nbsp; 就提取出来了ACE_InputCDR::to_boolean(Byte_order)和length，请问这是怎么回事儿？ <br>是这两个部分的内容是按某种规定好的顺序就保存在cdr中的么？还是说在operator&gt; &gt; ()重载时，就已经对&gt; &gt; 后面的变量类型做了多态，以致&gt; &gt; 后面的内容类型不同，就自动从cdr中提取出不同的信息作为输出？ <br><br>问题二 &nbsp; puzzle和puzzle3处 <br>这两句代码书中的解释是cdr提取出payload中的&#8220;字节序标志&#8221;（byte_order）。然后，根据输入中指定的字节顺序，确定CDR流的字节顺序，提取具有不定长度的日志记录payload的长度。 <br><br>我的疑问是，既然cdr需要知道payloay的&#8220;字节顺序标志&#8221;（cdr.reset_byte_order(byte_order)），然后再提取 payload的长度（cdr &nbsp; &gt; &gt; &nbsp; length）。那么cdr &nbsp; &gt; &gt; &nbsp; ACE_InputCDR::to_boolean(byte_order)这句是从哪里提取出来的&#8220;字节顺序标志&#8221;，我怎么感觉就是从payloade 里提取出来的呢（ACE_InputCDR &nbsp; cdr(payload)）？ <br><br>盼各位执教，十分感谢！！ <br><br>
<table style="HEIGHT: 100%" cellSpacing=0>
    <tbody>
        <tr>
            <td class=content id=reply46789862_body csdnid="Reply_Body" name="reply_body">自己看看ACE的源码不就很清楚了．．我们接收到一个数据包之后（数据存放在ACE_Message_Block中），用ACE_InputCDR来对接收到数据进行解编（解析）， <br>那个byte_order就是接收到的数据的字节序标记．然后通过cdr.reset_byte_order(byte_order)告诉 ACE_InputCDR，它内部的ACE_Message_Block保存的数据是啥字字节序．．如果接收的数据的字节序和本地字节序不一样，那么 ACE_InputCDR解编的时候就会自动在内部进行字节序的转换</td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cppblog.com/deadpunk/aggbug/44858.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deadpunk/" target="_blank">活着就是折腾，所以当然要骠悍的折腾</a> 2008-03-19 15:44 <a href="http://www.cppblog.com/deadpunk/archive/2008/03/19/44858.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转载：Windows同步API （一）—— Mutex </title><link>http://www.cppblog.com/deadpunk/archive/2008/01/31/42271.html</link><dc:creator>活着就是折腾，所以当然要骠悍的折腾</dc:creator><author>活着就是折腾，所以当然要骠悍的折腾</author><pubDate>Thu, 31 Jan 2008 02:26:00 GMT</pubDate><guid>http://www.cppblog.com/deadpunk/archive/2008/01/31/42271.html</guid><wfw:comment>http://www.cppblog.com/deadpunk/comments/42271.html</wfw:comment><comments>http://www.cppblog.com/deadpunk/archive/2008/01/31/42271.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deadpunk/comments/commentRss/42271.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deadpunk/services/trackbacks/42271.html</trackback:ping><description><![CDATA[<p>原文地址：<a href="http://www.cppblog.com/wangjt/archive/2008/01/30/42235.html">http://www.cppblog.com/wangjt/archive/2008/01/30/42235.html</a><br><br>Mutex是互斥体的意思，当一个线程持有一个Mutex时，其它线程申请持有同一个Mutex会被阻塞，因此可以通过Mutex来保证对某一资源的互斥访问（即同一时间最多只有一个线程访问）。<br>调用CreateMutex可以创建或打开一个Mutex对象，其原型如下</p>
<p>HANDLE CreateMutex(<br>&nbsp; LPSECURITY_ATTRIBUTES lpMutexAttributes,<br>&nbsp; BOOL bInitialOwner,<br>&nbsp; LPCTSTR lpName<br>);</p>
<p>其中参数lpMutexAttributes用来设定Mutex对象的安全描述符和是否允许子进程继承句柄。bInitialOwner表明是否将Mutex的持有者设置为调用线程。lpName参数设置Mutex的名字，该名字区分大小写并不能包含"\"，最大长度为MAX_PATH，可设置为NULL表明该Mutex为匿名对象。<br>如果调用成功，则返回Mutex的句柄，否则返回NULL，如果lpName不为NULL且调用前同名的Mutex已被创建，则返回同名Mutex的句柄，此时调用GetLastError将返回ERROR_ALREADY_EXISTS，参数bInitialOwner将被忽略。</p>
<p>还可以调用OpenMutex打开创建的非匿名Mutex，原型如下</p>
<p>HANDLE OpenMutex(<br>&nbsp; DWORD dwDesiredAccess,<br>&nbsp; BOOL bInheritHandle,<br>&nbsp; LPCTSTR lpName<br>);</p>
<p>在成功创建或打开Mutex后，可以使用wait functions来等待并获取Mutex的持有权。</p>
<p>下面的例子用来通过Mutex对象控制某一应用程序只运行一次</p>
<p>&nbsp;&nbsp;&nbsp; int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HANDLE hMutex = CreateMutex(NULL, FALSE, "Mutex_Only_One_Instance_Allowed");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (NULL == hMutex)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Error("Create mutex error.");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dw = WaitForSingleObject(hMutex, 0);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (WAIT_FAILED == dw)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Error("Wait for mutex error.");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CloseHandle(hMutex); // 释放句柄，当指向同一系统对象的所有句柄释放后，该对象将被删除。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (WAIT_TIMEOUT == dw)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 另外一个实例正在运行<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CloseHandle(hMutex);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 没有其它实例在运行，本实例将继续运行<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 在此实现必要的功能性代码，如创建窗口，进入消息循环<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // ...............</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ReleaseMutex(hMutex); // 释放hMutex的持有权，注意这并不等同于删除Mutex对象<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CloseHandle(hMutex);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>&nbsp;&nbsp;&nbsp; }</p>
<p>其中WaitForSingleObject是等待特定对象发出信号（signaled），而Mutex对象在没有任何线程持有时会发出信号。</p>
<img src ="http://www.cppblog.com/deadpunk/aggbug/42271.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deadpunk/" target="_blank">活着就是折腾，所以当然要骠悍的折腾</a> 2008-01-31 10:26 <a href="http://www.cppblog.com/deadpunk/archive/2008/01/31/42271.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转载：线程漫谈</title><link>http://www.cppblog.com/deadpunk/archive/2008/01/15/41206.html</link><dc:creator>活着就是折腾，所以当然要骠悍的折腾</dc:creator><author>活着就是折腾，所以当然要骠悍的折腾</author><pubDate>Tue, 15 Jan 2008 10:16:00 GMT</pubDate><guid>http://www.cppblog.com/deadpunk/archive/2008/01/15/41206.html</guid><wfw:comment>http://www.cppblog.com/deadpunk/comments/41206.html</wfw:comment><comments>http://www.cppblog.com/deadpunk/archive/2008/01/15/41206.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deadpunk/comments/commentRss/41206.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deadpunk/services/trackbacks/41206.html</trackback:ping><description><![CDATA[<div class=postTitle><a id=viewpost1_TitleUrl href="http://www.cppblog.com/CppExplore/archive/2008/01/15/41175.html"><font color=#000080>系统设计之 线程漫谈</font></a> </div>
<div class=postText>
<p>废话不多说，详细介绍使用线程的优点好处请参考baidu、google。<br><strong>一、线程使用场景。</strong>使用线程的方式大致有两种：<br>（1）流水线方式。根据业务特点，将一个流程的处理分割成多个线程，形成流水线的处理方式。产生的结果:延长单一流程的处理时间，提高系统整体的吞吐能力。<br>（2）线程池方式。针对处理时间比较长且没有内蕴状态的线程，使用线程池方式分流消息，加快对线程消息的处理，避免其成为系统瓶颈。<br>线程使用的关键是 线程消息队列、线程锁、智能指针 的 使用。其中以线程消息队列最为重要。<br><br><strong>二、线程消息队列描述</strong>。所谓线程消息队列，就是一个普通的循环队列（其它数据结构也未尝不可，具体内容请参考数据结构课本）加上&#8220;多生产者－单（多）消费者的PV操作&#8221;（详细内容请参考操作系统课本）。流水线方式中的线程是单消费者，线程池方式中的线程是多消费者。<br>为了后文更好的描述问题，作如下说明：<br>（1）假定循环队列CircleQueue中,存放的消息指针类型是MyMSG *,入队操作EnQueue,出队操作DeQueue，判断队满IsQueueFull，判断队空IsQueueEmpty。<br>（2）生产者消费者：生产者线程生产消息(MyMSG *)，放在一个空缓冲区(CircleQueue)中，供消费者线程消费，生产者生产消息(EnQueue)，如果缓冲区满(IsQueueFull)，则被阻塞，消费者消费消息(DeQueue)，如果缓冲区空(IsQueueEmpty)，则被阻塞。线程消息队列就是生产者消费者问题中的缓冲区，而它的生产者是不限定的，任何线程都可以作为生产者向其中进行EnQueue操作，消费线程则可能是一个，也可能是多个。因此对循环队列的任何操作都要加锁，以保证线程安全。<br>PV操作和锁机制的基础都是信号量。下面列出posix标准中给出的有关信号量的操作:</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">semaphore.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;sem_init(sem_t&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">sem,&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;pshared,&nbsp;unsigned&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;value);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;sem_wait(sem_t&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;sem);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;sem_trywait(sem_t&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;sem);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;sem_post(sem_t&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;sem);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;sem_getvalue(sem_t&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;sem,&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;sval);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;sem_destroy(sem_t&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;sem);</span></div>
<p>各个函数的详细用法，请在linux/unix上查看man。</p>
<p><strong>三、线程消息队列实现。</strong>基于以上讨论，下面给出线程消息队列的实现(仅为了说明问题，非标准可运行代码)。<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;ThreadQueue<br><img id=Codehighlighter1_18_114_Open_Image onclick="this.style.display='none'; Codehighlighter1_18_114_Open_Text.style.display='none'; Codehighlighter1_18_114_Closed_Image.style.display='inline'; Codehighlighter1_18_114_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top></span><span id=Codehighlighter1_18_114_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id=Codehighlighter1_18_114_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;CircleQueue&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;queue;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;nFull;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;nEmpty;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;sem_t&nbsp;lock;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;sem_t&nbsp;fullCond;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;sem_t&nbsp;emptyCond<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;createThreadQueue()<br><img id=Codehighlighter1_142_266_Open_Image onclick="this.style.display='none'; Codehighlighter1_142_266_Open_Text.style.display='none'; Codehighlighter1_142_266_Closed_Image.style.display='inline'; Codehighlighter1_142_266_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top></span><span id=Codehighlighter1_142_266_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id=Codehighlighter1_142_266_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;createCircleQueue(queue);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;nFull</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;nEmpty</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;sem_ini(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">lock,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;sem_init(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">fullCond,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;sem_init(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">emptyCond,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;putq(MyMSG&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;msg)<br><img id=Codehighlighter1_291_507_Open_Image onclick="this.style.display='none'; Codehighlighter1_291_507_Open_Text.style.display='none'; Codehighlighter1_291_507_Closed_Image.style.display='inline'; Codehighlighter1_291_507_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top></span><span id=Codehighlighter1_291_507_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id=Codehighlighter1_291_507_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;sem_wait(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">lock);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(IsQueueFull(queue))<br><img id=Codehighlighter1_336_422_Open_Image onclick="this.style.display='none'; Codehighlighter1_336_422_Open_Text.style.display='none'; Codehighlighter1_336_422_Closed_Image.style.display='inline'; Codehighlighter1_336_422_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_336_422_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id=Codehighlighter1_336_422_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nFull</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sem_post(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">lock);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sem_wait(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">fullCond);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sem_wait(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">lock);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nFull</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;EnQueue(queue,msg);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(nEmpty</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)<br><img id=Codehighlighter1_460_487_Open_Image onclick="this.style.display='none'; Codehighlighter1_460_487_Open_Text.style.display='none'; Codehighlighter1_460_487_Closed_Image.style.display='inline'; Codehighlighter1_460_487_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_460_487_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id=Codehighlighter1_460_487_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sem_post(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">emptyCond);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;sem_post(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">lock);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;getq(MyMSG&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;msg)<br><img id=Codehighlighter1_532_744_Open_Image onclick="this.style.display='none'; Codehighlighter1_532_744_Open_Text.style.display='none'; Codehighlighter1_532_744_Closed_Image.style.display='inline'; Codehighlighter1_532_744_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top></span><span id=Codehighlighter1_532_744_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id=Codehighlighter1_532_744_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;sem_wait(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">lock);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(IsQueueEmpty(queue))<br><img id=Codehighlighter1_578_667_Open_Image onclick="this.style.display='none'; Codehighlighter1_578_667_Open_Text.style.display='none'; Codehighlighter1_578_667_Closed_Image.style.display='inline'; Codehighlighter1_578_667_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_578_667_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id=Codehighlighter1_578_667_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nEmpty</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sem_post(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">lock);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sem_wait(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">emptyCond);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sem_wait(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">lock);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nEmpty</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;DeQueue(msg);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(nFull</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)<br><img id=Codehighlighter1_698_724_Open_Image onclick="this.style.display='none'; Codehighlighter1_698_724_Open_Text.style.display='none'; Codehighlighter1_698_724_Closed_Image.style.display='inline'; Codehighlighter1_698_724_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_698_724_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id=Codehighlighter1_698_724_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sem_post(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">fullCond);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;sem_post(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">lock);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;destroyThreadQueue()<br><img id=Codehighlighter1_772_874_Open_Image onclick="this.style.display='none'; Codehighlighter1_772_874_Open_Text.style.display='none'; Codehighlighter1_772_874_Closed_Image.style.display='inline'; Codehighlighter1_772_874_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top></span><span id=Codehighlighter1_772_874_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id=Codehighlighter1_772_874_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;destroyCircleQueue(queue);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;sem_destroy(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">lock);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;sem_destroy(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">fullCond);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;sem_destroy(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">emptyCond);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br></span></div>
</div>
<img src ="http://www.cppblog.com/deadpunk/aggbug/41206.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deadpunk/" target="_blank">活着就是折腾，所以当然要骠悍的折腾</a> 2008-01-15 18:16 <a href="http://www.cppblog.com/deadpunk/archive/2008/01/15/41206.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC制作屏幕保护程序</title><link>http://www.cppblog.com/deadpunk/archive/2007/11/22/37117.html</link><dc:creator>活着就是折腾，所以当然要骠悍的折腾</dc:creator><author>活着就是折腾，所以当然要骠悍的折腾</author><pubDate>Thu, 22 Nov 2007 02:04:00 GMT</pubDate><guid>http://www.cppblog.com/deadpunk/archive/2007/11/22/37117.html</guid><wfw:comment>http://www.cppblog.com/deadpunk/comments/37117.html</wfw:comment><comments>http://www.cppblog.com/deadpunk/archive/2007/11/22/37117.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deadpunk/comments/commentRss/37117.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deadpunk/services/trackbacks/37117.html</trackback:ping><description><![CDATA[<strong><font style="BACKGROUND-COLOR: #ffff66">VC</font></strong>5.0/6.0是开发<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序的好工具。静态链接库SCRNSAVE.LIB对<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序提供了支持。SCRNSAVE.LIB包含了建立<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序的主程序和缺省功能，用户可以方便地使用SDK进行编程并与之连接。尽管SDK编程相对MFC麻烦，但编写相对简单的<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序却相当容易甚至比用MFC编程更简单。 <br>　　也可以使用MFC编写<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序。但遗憾的是MFC不支持SCRNSAVE.LIB，必须手工完成原来由SCRNSAVE.LIB提供的功能，比较麻烦和不好理解。不过，编写复杂的<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序时，MFC对于显示模块和对话框处理可以提供比SDK方便得多的功能。为简单起见先介绍如何使用SDK编写<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序。 <br><br><br>一. <strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序和SCRNSAVE.LIB <br><br>　　先从开发者的角度对<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序说明如下： <br>　　首先，<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序是Win32 API 支持一种特殊的应用程序并由系统自动激活。其机制是当条件满足时，系统向当前活动窗口发出字参数 wParam 值为SC_SCREENSAVE 的WM_SYSCOMMAND消息，然后由当前活动窗口执行SYSTEM.INI文件中[boot]区指定的<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序。 <br><br>　　<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序激活的条件是 <br>　　1. 在规定时间内没有鼠标或键盘输入. <br>　　2. 当前的活动窗口是标准的WINDOWS应用程序。因为非WINDOWS应用，不会理睬WM_SYSCOMMAND消息。 <br>　　3. 显然，如果当前活动的程序接管了字参数 wParam 值为SC_SCREENSAVE 的WM_SYSCOMMAND 消息并且不传递到 DefWindowProc函数就可以禁止<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序。这对某些运行中不愿意被打断的程序如视频播放，光盘刻录程序特别有用。 <br><br>　　其次，可以在控制面板的显示器中选择需要的<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序，并可以配置<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序的参数。<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序应该提供配置<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序的对话框。 <br><br>　　再次,<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序有特别的输出函数，资源定义和变量声明。SCRNSAVE.LIB包含了建立<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序的主程序。<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序启动时SCRNSAVE.LIB自动创建一全屏窗口，并描述窗口类为无光标的满黑屏。 <br>　　用户编写的<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序必须包含三个基本函数ScreenSaverProc，ScreenSaverConfigureDialog 和RegisterDialogClasses 并与SCRNSAVE.LIB连接。 <br>　　1．ScreenSaverProc 窗口函数处理特定的消息并把未处理的消息传递给SCRNSAVE.LIB 。ScreenSaverProc 一般处理以下消息： <br>　　WM_CREATE 读取.INI或注册表的初始化数据，设置定时器以及其他初始化操作。 <br>　　WM_ERASEBKGND 擦除背景为下一步绘图作准备。 <br>　　WM_TIMER 进行绘图输出。用户可以实现自己的动画功能以及其他操作。 <br>　　WM_DESTROY 删除定时器以及其他对象 <br>　　ScreenSaverProc 把未处理的消息传递到SCRNSAVE.LIB中的 DefScreenSaverProc函数 处理。由它完成许多复杂和关键的操作比如何时激活，何时关闭等，大大方便了<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序的编写。 <br>　　2．ScreenSaverConfigureDialog函数处理<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序配置对话框。该对话框由控制面板的显示器设置程序调用。用户输入的配置数据输出到.INI或注册表中。 <br>　　3. RegisterDialogClasses函数登记<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序配置对话框的窗口类。如果不使用特殊的窗口或控件，可以简单地返回TRUE。 <br><br>　　另外，编写<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序还有一些原则。 <br>　　1. 为使控制面板能够识别，<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序的扩展名必须改为.SCR并存放在WINDOWS目录下。 <br>　　2. <strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序的图标（ICON）在资源文件中必须定义为ID_APP。ID_APP由系统的SCRNSAVE.H.定义。 <br>　　3. 资源文件中必须包含一描述字符串。该字符串用于控制面板显示<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序的名字。它必须位于字符串表的首位。SCRNSAVE.H.定义其ID为1。 <br>　　4. 资源文件中<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序配置对话框的ID必须为DLG_SCRNSAVECONFIGURE。它由系统的SCRNSAVE.H.定义。 <br><br><br>二.编程实例 <br><br>　　1.最小的<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序MiniSaver。这是一个仅包含最基本模块的<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序，运行时在屏幕上显示一行活动的文字。步骤如下: <br>　　第一步，在<strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">VC</strong>5.0/6.0中建立32位应用工程(不选MFC WIZARD EXE).建立如下的MiniSaver.CPP文件： <br>#include <br>#include<br>// SCRNSAVE.LIB的头文件<br>#include "resource.h"<br>//声明三个基本的函数<br>LRESULT WINAPI ScreenSaveProc<br>(HWND,UINT,WPARAM,LPARAM);<br>BOOL WINAPI ScreenSaveConfigureDialog<br>(HWND,UINT,WPARAM,LPARAM);<br>BOOL WINAPI RegisterDialogClasses(HINSTANCE);<br>//定义三个基本的函数<br>LRESULT WINAPI ScreenSaverProc<br>(HWND hWnd, UINT message, WPARAM wParam,<br>LPARAM lParam)<br>{ HDC hDC;<br>RECT rc;<br>static int xpos;//文本的横坐标<br>static char SlideText[]="欢迎使用<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序!";<br>static UINT timerID;//定时器<br>switch (message)<br>{<br>case WM_CREATE:<br>xpos=0;<br>timerID=SetTimer(hWnd,1,250,NULL);//设置定时器<br>break;<br><br>case WM_ERASEBKGND:<br>//空操作，交由DefScreenSaverProc处理<br>break;<br>case WM_TIMER:<br>hDC=GetDC(hWnd);<br>//清屏<br>SetRect(&amp;rc,0,0,GetSystemMetrics(SM_CXSCREEN),<br>GetSystemMetrics(SM_CYSCREEN))<br>FillRect(hDC,&amp;rc,GetStockObject(BLACK_BRUSH));<br>//输出文本<br>SetTextColor(hDC,RGB(255*rand(),<br>255*rand(),255*rand()));<br>SetBkColor(hDC,RGB(0,0,0));<br>TextOut(hDC,xpos,GetSystemMetrics(SM_CYSCREEN)/2,<br>SlideText,strlen(SlideText));<br>//移动文本的横坐标<br>xpos=(xpos+10)%GetSystemMetrics(SM_CXSCREEN);<br>ReleaseDC(hWnd,hDC);<br>break;<br><br>case WM_DESTROY:<br>KillTimer(hWnd,timerID);//删除定时器<br>PostQuitMessage (0);<br>return 0;<br>}<br>return DefScreenSaverProc<br>(hWnd,message,wParam,lParam);<br>}<br><br>BOOL WINAPI ScreenSaverConfigureDialog<br>(HWND hWnd,UINT message,WPARAM wParam,<br>LPARAM lParam)<br>{//暂时不需要配置对话框，仅返回FALSE<br>return FALSE;<br>}<br><br>BOOL WINAPI RegisterDialogClasses<br>(HINSTANCE hInstance)<br>{//一般不需要，仅返回TRUE <br>return TRUE;<br>}<br><br><br>　　第二步，定义资源文件MiniSaver.rc。在<strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">VC</strong>环境下生成一图标，其ID为ID_APP。向字符串表加入ID为IDS_DESCRIPTION字符串"MiniSaver"，并作为字符串表第一项 <br>　　第三步，编译连接并将生成的MiniSaver.EXE更名为MiniSaver.SCR拷入WINDOWS目录。注意, 编译前一定要在Project菜单的Setting中的Link选项中加上SCRNSAVE.LIB库。 <br>　　第四步，控制面板的显示器设置中选择<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序MiniSaver就可以使用了。注意不要急于配置<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序，因为MiniSaver还有没提供配置对话框。 <br><br>　　2.较完整的<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序MySaver。该<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序提供了配置对话框和关于对话框，并且使用了图象显示。读者可以将自己喜爱的图象加到资源中。 <br>　　第一步，在<strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">VC</strong>5.0/6.0中建立32位应用工程(不选MFC WIZARD EXE)并定义资源文件MiniSaver.rc。 <br>　　　　在<strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">VC</strong>环境下生成一图标，其ID为ID_APP。 <br>　　　　向字符串表加入ID为IDS_DESCRIPTION字符串"MiniSaver"，并作为字符串表第一项。加入ID为idsAPPName<br>　　　　字符串"Screen Saver.MySaver"，说明见后面程序。 <br>　　　　加入ID为IDB_BITMAP1的位图 <br>　　　　加入ID为DLG_ABOUT对话框。仅有一ID为IDOK的按钮 <br>　　　　加入ID为ID_APP。此对话的ID由SCRNSAVE.H定义且只能为DLG_SCRNSAVECONFIGURE。其中有ID为IDC_EDIT<br>　　　　的EDIT控件，ID为IDOK，IDCANCEL和IDABOUT的按钮。 <br>　　　　值得注意的是RESOURCE.H定义的ID_APP和DLG_SCRNSAVECONFIGURE可能与SCRNSAVE.H预定义的值冲突，可<br>　　　　手动地将RESOURCE.H中的ID_APP设为100，DLG_SCRNSAVECONFIGURE设为2003即可。 <br>　　第二步，建立如下的MySaver.CPP文件： <br>#include #include <br><br>#include "resource.h"<br>//声明三个基本的函数<br>LRESULT WINAPI ScreenSaveProc<br>(HWND,UINT,WPARAM,LPARAM);<br>BOOL WINAPI ScreenSaveConfigureDialog<br>(HWND,UINT,WPARAM,LPARAM);<br>BOOL WINAPI RegisterDialogClasses(HINSTANCE);<br>BOOL WINAPI AboutDialog(HWND,UINT,WPARAM,LPARAM);<br>//定义全局变量<br>char szIniFileName[]="control.ini";<br>//<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序配置数据存放在control.ini文件<br>char szSection[32];<br>//<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序配置数据在control.ini文件位置区名称<br>char szEntry[]="Slide Text:";<br>//<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序配置数据项名称<br>char SlideText[256];<br>//<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序配置数据，这里是文本内容<br>//定义三个基本的函数<br>LRESULT WINAPI ScreenSaverProc<br>(HWND hWnd,UINT message, WPARAM wParam,<br>LPARAM lParam)<br>{ static HBITMAP hBmp;//位图句柄<br>HDC hDC,hMemDC;//hMemDC是内存设备，缓存位图。<br>RECT rc;<br>static int xpos=0;<br>static UINT timerID;<br>switch (message)<br>{<br>case WM_CREATE:<br>//文件位置区名称szSection赋值为资源<br>idsAPPName。其中hMainInstance为//SCRNSAVE.LIB<br>定义的<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序实例句柄<br>LoadString(hMainInstance,idsAPPName,<br>szSection,sizeof(szSection));<br>strcpy(SlideText,"欢迎使用<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序!");<br>//读control.ini文件中[Screen Saver.MySaver]<br>区的配置数据到SlideText<br>GetPrivateProfileString(szSection,szEntry, <br>SlideText,SlideText,<br>sizeof(SlideText),szIniFileName); <br>//取位图<br>hBmp=LoadBitmap(hMainInstance,<br>MAKEINTRESOURCE(IDB_BITMAP1));<br>timerID=SetTimer(hWnd,1,250,NULL);<br>break;<br><br>case WM_ERASEBKGND:<br>hDC=GetDC(hWnd);<br>//显示位图<br>hMemDC=CreateCompatibleDC(hDC);<br>SelectObject(hMemDC,hBmp);<br>SetRect(&amp;rc,0,0,GetSystemMetrics(SM_CXSCREEN),<br>GetSystemMetrics(SM_CYSCREEN)-25);<br>BitBlt(hDC,rc.top,rc.left,rc.right,rc.bottom,<br>hMemDC,rc.top,rc.left,SRCCOPY);<br>//清除底行，为文本显示作准备。<br>SetRect(&amp;rc,0,GetSystemMetrics(SM_CYSCREEN)-25<br>GetSystemMetrics(SM_CXSCREEN)，<br>GetSystemMetrics(SM_CYSCREEN));<br>FillRect(hDC,&amp;rc,GetStockObject(BLACK_BRUSH));<br>ReleaseDC(hWnd,hDC);<br>DeleteDC(hMemDC);<br>return 1;<br><br>case WM_TIMER:<br>hDC=GetDC(hWnd);<br>//清除底行<br>SetRect(&amp;rc,0,GetSystemMetrics(SM_CYSCREEN)-25,<br>GetSystemMetrics(SM_CXSCREEN),<br>GetSystemMetrics(SM_CYSCREEN));<br>FillRect(hDC,&amp;rc,GetStockObject(BLACK_BRUSH));<br>//输出文本<br>SetTextColor(hDC,RGB(255*rand(),<br>255*rand(),255*rand()));<br>SetBkColor(hDC,RGB(0,0,0));<br>TextOut(hDC,xpos,GetSystemMetrics(SM_CYSCREEN)-25,<br>SlideText,strlen(SlideText));<br>xpos=(xpos+10)%GetSystemMetrics(SM_CXSCREEN);<br>ReleaseDC(hWnd,hDC);<br>break;<br><br>case WM_DESTROY:<br>DeleteObject(hBmp);<br>KillTimer(hWnd,timerID);<br>PostQuitMessage (0);<br>return 0;<br>}<br>return DefScreenSaverProc<br>(hWnd,message,wParam,lParam);<br>}<br><br>BOOL WINAPI ScreenSaverConfigureDialog<br>(HWND hWnd,UINT message,WPARAM wParam,<br>LPARAM lParam)<br>{ switch (message)<br>{<br>case WM_INITDIALOG:<br>LoadString(hMainInstance,idsAPPName,<br>szSection,sizeof(szSection));<br>strcpy(SlideText,"欢迎使用<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">屏幕保护</strong>程序!");<br>GetPrivateProfileString(szSection,<br>szEntry,SlideText,<br>SlideText,sizeof(SlideText),szIniFileName); <br>SetDlgItemText(hWnd,IDC_EDIT,SlideText);<br>SetFocus(GetDlgItem(hWnd,IDC_EDIT));<br>return FALSE;<br><br>case WM_COMMAND:<br>switch(wParam)<br>{<br>case IDOK:<br>//取EDIT控件文本数据并写入control.ini文件<br>GetDlgItemText(hWnd,IDC_EDIT,<br>SlideText,sizeof(SlideText));<br>WritePrivateProfileString(szSection,<br>szEntry,SlideText,szIniFileName);<br>EndDialog(hWnd,TRUE);<br>return TRUE;<br><br>case IDCANCEL:<br>EndDialog(hWnd,FALSE);<br>return TRUE;<br><br>case IDABOUT:<br>//调用ABOUT对话框<br>DialogBox(hMainInstance, <br>MAKEINTRESOURCE(DLG_ABOUT),<br>hWnd,(FARPROC)AboutDialog);<br>return TRUE;<br>}<br>break;<br>}<br>return FALSE;<br>}<br><br>BOOL WINAPI RegisterDialogClasses<br>(HINSTANCE hInstance)<br>{<br>return TRUE;<br>}<br><br>BOOL WINAPI AboutDialog<br>(HWND hWnd,UINT message,WPARAM wParam,<br>LPARAM lParam)<br>{ <br>switch (message)<br>{<br>case WM_INITDIALOG:<br>return TRUE;<br><br>case WM_COMMAND:<br>switch(wParam)<br>{<br>case IDOK:<br>EndDialog(hWnd,TRUE);<br>return TRUE;<br>}<br>break;<br>}<br>return FALSE;<br>}<br><br>　　 最后，编译连接并将生成的MiniSaver.EXE更名为MiniSaver.SCR拷入WINDOWS目录。此时可以使用配置对话框了。<br>
<img src ="http://www.cppblog.com/deadpunk/aggbug/37117.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deadpunk/" target="_blank">活着就是折腾，所以当然要骠悍的折腾</a> 2007-11-22 10:04 <a href="http://www.cppblog.com/deadpunk/archive/2007/11/22/37117.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转载)WinDBG(CDB)实践1-新手指南 </title><link>http://www.cppblog.com/deadpunk/archive/2007/06/12/26188.html</link><dc:creator>活着就是折腾，所以当然要骠悍的折腾</dc:creator><author>活着就是折腾，所以当然要骠悍的折腾</author><pubDate>Tue, 12 Jun 2007 09:29:00 GMT</pubDate><guid>http://www.cppblog.com/deadpunk/archive/2007/06/12/26188.html</guid><wfw:comment>http://www.cppblog.com/deadpunk/comments/26188.html</wfw:comment><comments>http://www.cppblog.com/deadpunk/archive/2007/06/12/26188.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deadpunk/comments/commentRss/26188.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deadpunk/services/trackbacks/26188.html</trackback:ping><description><![CDATA[原文地址：<a href="http://www.cppblog.com/sandy/archive/2007/03/13/19723.html">http://www.cppblog.com/sandy/archive/2007/03/13/19723.html</a><br><font color=#ff0000>Step1</font> <br>下载最新的Debugging Tools for windows <a href="http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx"><font color=#1d58d1>http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx</font></a><br>最新版本是6.6.7.5 <a href="http://msdl.microsoft.com/download/symbols/debuggers/dbg_x86_6.6.07.5.exe"><font color=#1d58d1>http://msdl.microsoft.com/download/symbols/debuggers/dbg_x86_6.6.07.5.exe</font></a><br>(BTW,如果使用老版本可能出现"The call to LoadLibrary(ext) failed, Win32 error 127. The specified procedure could not be found."这样的错误信息)<br><br><font color=#ff0000>Step2<br></font>设置好symbol server的环境变量<br>Set _NT_SYMBOL_PATH=srv*c:\symbols*http://msdl.microsoft.com/download/symbols<br>创建好c:\symbols目录<br>(BTW,如果要设置http代理set _NT_SYMBOL_PROXY=proxy_server:port)<br><br><font color=#ff0000>Step3<br></font>把WinDBG(CDB)安装路径加到path中(默认是C:\Program Files\Debugging Tools for Windows)<br>设置CDB为默认的JIT debugger<br><font style="BACKGROUND-COLOR: #000000" color=#ffffff>C:\&gt;cdb -iae<br></font><br><font color=#ff0000>Step4</font><br>使用vc6创建一个控制台程序Crash，主程序为crash.cpp<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">//</span><span style="COLOR: #000000">&nbsp;Crash.cpp&nbsp;:&nbsp;Defines&nbsp;the&nbsp;entry&nbsp;point&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;the&nbsp;console&nbsp;application.<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #000000">//</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">stdafx.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;argv[])<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i)<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello&nbsp;World!%s\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,i);<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<p>可以看到该程序就第九行有一个错误,%s应该写成%d<br><br><font color=#ff0000>Step 5<br></font>编译生成release版本(这里我主要针对Release程序)<br>注意设置<br><img height=446 alt=crash1.jpg src="http://www.cppblog.com/images/cppblog_com/sandy/crash1.jpg" width=677 border=0><br><br><br><img height=446 alt=crash2.jpg src="http://www.cppblog.com/images/cppblog_com/sandy/crash2.jpg" width=677 border=0><br><br>最后会生成Crash.exe和Crash.pdb和其他一些中间文件<br><br><font color=#ff0000>Step 6<br></font>运行Release版本的crash.exe会出现crash,这时CDB会自动attach到该进程，开始调试<br>出现如下画面<br><br><font style="BACKGROUND-COLOR: #000000" color=#ffffff>Hello World!(null)</font></p>
<p><font style="BACKGROUND-COLOR: #000000" color=#ffffff>Microsoft (R) Windows Debugger&nbsp; Version 6.6.0007.5<br>Copyright (c) Microsoft Corporation. All rights reserved.<br></font><font style="BACKGROUND-COLOR: #000000" color=#ffffff>*** wait with pending attach&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>Symbol search path is: srv*c:\symbols*http://msdl.microsoft.com/download/symbols<br></font><font style="BACKGROUND-COLOR: #000000" color=#ffffff>Executable search path is:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>ModLoad: 00400000 0040c000&nbsp;&nbsp; D:\Test\Crash\Release\Crash.exe&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>ModLoad: 77f80000 77ffc000&nbsp;&nbsp; C:\WINNT\system32\ntdll.dll&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <br>ModLoad: 7c570000 7c624000&nbsp;&nbsp; C:\WINNT\system32\KERNEL32.dll&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; <br>(e04.f18): Access violation - code c0000005 (!!! second chance !!!)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>eax=00000001 ebx=7ffdf073 ecx=00000001 edx=7fffffff esi=7ffffffe edi=00000800<br>eip=004016dd esp=0012fcf8 ebp=0012ff50 iopl=0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nv up ei pl nz na pe nc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>cs=001b&nbsp; ss=0023&nbsp; ds=0023&nbsp; es=0023&nbsp; fs=0038&nbsp; gs=0000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; efl=00000206&nbsp;&nbsp;&nbsp; <br>*** WARNING: Unable to verify checksum for D:\Test\Crash\Release\Crash.exe&nbsp;&nbsp;&nbsp;&nbsp; <br>Crash!_output+0x49a:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>004016dd 803800&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmp&nbsp;&nbsp;&nbsp;&nbsp; byte ptr [eax],0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ds:0023:00000001=??&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>0:000&gt;<br></font><br>输入.lines load source code information<br>输入k命令查看堆栈<br><br>0:000&gt; .lines<br>Line number information will be loaded<br>0:000&gt; k<br>ChildEBP RetAddr<br>0012ff50 0040103f Crash!_output+0x49a<br>0012ff70 0040100e Crash!printf+0x1f<br><strong>0012ff80 00401105 Crash!main+0xe [D:\Test\Crash\Crash.cpp @ 9]<br></strong>0012ffc0 7c5989a5 Crash!mainCRTStartup+0xb4<br>0012fff0 00000000 KERNEL32!BaseProcessStart+0x3d<br><br>可以发现程序在Crash.cpp第9行crash<br><br>输入q命令退出cdb,结束调试。<br></p>
<img src ="http://www.cppblog.com/deadpunk/aggbug/26188.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deadpunk/" target="_blank">活着就是折腾，所以当然要骠悍的折腾</a> 2007-06-12 17:29 <a href="http://www.cppblog.com/deadpunk/archive/2007/06/12/26188.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>