﻿<?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++博客-Robertxiao-随笔分类-RPC/COM/ATL散谈</title><link>http://www.cppblog.com/Robertxiao/category/5518.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 04 Mar 2011 18:52:55 GMT</lastBuildDate><pubDate>Fri, 04 Mar 2011 18:52:55 GMT</pubDate><ttl>60</ttl><item><title>拆解一个RPC工具包</title><link>http://www.cppblog.com/Robertxiao/archive/2011/03/04/141105.html</link><dc:creator>Robertxiao</dc:creator><author>Robertxiao</author><pubDate>Fri, 04 Mar 2011 05:41:00 GMT</pubDate><guid>http://www.cppblog.com/Robertxiao/archive/2011/03/04/141105.html</guid><wfw:comment>http://www.cppblog.com/Robertxiao/comments/141105.html</wfw:comment><comments>http://www.cppblog.com/Robertxiao/archive/2011/03/04/141105.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Robertxiao/comments/commentRss/141105.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Robertxiao/services/trackbacks/141105.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 由于我们现在所搭建的系统是基于分布式的系统，出于性能考虑决定基于RPC技术进行系统间的互操作与互通信。&nbsp;&nbsp;<a href='http://www.cppblog.com/Robertxiao/archive/2011/03/04/141105.html'>阅读全文</a><img src ="http://www.cppblog.com/Robertxiao/aggbug/141105.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Robertxiao/" target="_blank">Robertxiao</a> 2011-03-04 13:41 <a href="http://www.cppblog.com/Robertxiao/archive/2011/03/04/141105.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>适用于使用COM技术的日志记录</title><link>http://www.cppblog.com/Robertxiao/archive/2010/06/11/117644.html</link><dc:creator>Robertxiao</dc:creator><author>Robertxiao</author><pubDate>Fri, 11 Jun 2010 08:13:00 GMT</pubDate><guid>http://www.cppblog.com/Robertxiao/archive/2010/06/11/117644.html</guid><wfw:comment>http://www.cppblog.com/Robertxiao/comments/117644.html</wfw:comment><comments>http://www.cppblog.com/Robertxiao/archive/2010/06/11/117644.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Robertxiao/comments/commentRss/117644.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Robertxiao/services/trackbacks/117644.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一个适合于使用COM场合记录日志的模块.&nbsp;&nbsp;<a href='http://www.cppblog.com/Robertxiao/archive/2010/06/11/117644.html'>阅读全文</a><img src ="http://www.cppblog.com/Robertxiao/aggbug/117644.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Robertxiao/" target="_blank">Robertxiao</a> 2010-06-11 16:13 <a href="http://www.cppblog.com/Robertxiao/archive/2010/06/11/117644.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>64位操作系统下注册COM组件</title><link>http://www.cppblog.com/Robertxiao/archive/2009/08/24/94251.html</link><dc:creator>Robertxiao</dc:creator><author>Robertxiao</author><pubDate>Mon, 24 Aug 2009 05:55:00 GMT</pubDate><guid>http://www.cppblog.com/Robertxiao/archive/2009/08/24/94251.html</guid><wfw:comment>http://www.cppblog.com/Robertxiao/comments/94251.html</wfw:comment><comments>http://www.cppblog.com/Robertxiao/archive/2009/08/24/94251.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/Robertxiao/comments/commentRss/94251.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Robertxiao/services/trackbacks/94251.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 如何在64位系统下注册COM组件。&nbsp;&nbsp;<a href='http://www.cppblog.com/Robertxiao/archive/2009/08/24/94251.html'>阅读全文</a><img src ="http://www.cppblog.com/Robertxiao/aggbug/94251.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Robertxiao/" target="_blank">Robertxiao</a> 2009-08-24 13:55 <a href="http://www.cppblog.com/Robertxiao/archive/2009/08/24/94251.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个在脚本中枚举注册表键和值的工具</title><link>http://www.cppblog.com/Robertxiao/archive/2009/08/03/92047.html</link><dc:creator>Robertxiao</dc:creator><author>Robertxiao</author><pubDate>Mon, 03 Aug 2009 08:08:00 GMT</pubDate><guid>http://www.cppblog.com/Robertxiao/archive/2009/08/03/92047.html</guid><wfw:comment>http://www.cppblog.com/Robertxiao/comments/92047.html</wfw:comment><comments>http://www.cppblog.com/Robertxiao/archive/2009/08/03/92047.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Robertxiao/comments/commentRss/92047.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Robertxiao/services/trackbacks/92047.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在脚本中枚举注册表键和值的工具&nbsp;&nbsp;<a href='http://www.cppblog.com/Robertxiao/archive/2009/08/03/92047.html'>阅读全文</a><img src ="http://www.cppblog.com/Robertxiao/aggbug/92047.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Robertxiao/" target="_blank">Robertxiao</a> 2009-08-03 16:08 <a href="http://www.cppblog.com/Robertxiao/archive/2009/08/03/92047.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ATL 开源部份介绍</title><link>http://www.cppblog.com/Robertxiao/archive/2009/05/26/85845.html</link><dc:creator>Robertxiao</dc:creator><author>Robertxiao</author><pubDate>Tue, 26 May 2009 14:39:00 GMT</pubDate><guid>http://www.cppblog.com/Robertxiao/archive/2009/05/26/85845.html</guid><wfw:comment>http://www.cppblog.com/Robertxiao/comments/85845.html</wfw:comment><comments>http://www.cppblog.com/Robertxiao/archive/2009/05/26/85845.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Robertxiao/comments/commentRss/85845.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Robertxiao/services/trackbacks/85845.html</trackback:ping><description><![CDATA[&nbsp;
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2007</span><span>年三月份，</span><span>Visual C++</span><span>团队宣称将在</span><span><a href="http://www.codeplex.com%20%20网站上发布ATL">http://www.codeplex.com&nbsp;<span><span>网站上发布</span></span>ATL</a> Server</span><span>的源代码。在这份源码的基础之上，我们将有机会在</span><span>ATL Server</span><span>中加入新的特性。</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在</span><span>ATL&nbsp;Server</span><span>中，下列的部分已经公开</span></p>
<p><span><span>（1）<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>Core ATL Server Framework classes in atlisapi.h, atlstencil.h, atlserr.h</span></p>
<p><span><span>（2）<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>Caching classes in atlcache.h</span></p>
<p><span><span>（3）<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>Cryptography classes in atlcrypt.h</span></p>
<p><span><span>（4）<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>HTML generation on server side and reading on client sides in atlhtml.h</span></p>
<p><span><span>（5）<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>Performance monitoring classes in atlperf.h</span></p>
<p><span><span>（6）<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>Extension management classes in atlextmgmt.h</span></p>
<p><span><span>（7）<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>Server and client side support for SOAP based Web services in atlsharedsvc.h, atlsoap.h</span></p>
<p><span><span>（8）<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>Session-state classes and interfaces in atlsession.h</span></p>
<p><span><span>（9）<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>MIME/SMTP support in atlmime.h and atlsmtpconnection.h</span></p>
<p><span><span>（10）&nbsp;</span></span><span>Regular Expression support from atlrx.h</span></p>
<p><span><span>（11）&nbsp;</span></span><span>Stream helpers in atlsoap.h and atlhtml.h</span></p>
<p><span><span>（12）&nbsp;</span></span><span>Many of the ATL Server tutorials, samples and help pages.</span></p>
<p>&nbsp;</p>
<p><span>下表列出了公开的源文件，这些源文件可以直接在网上下载。</span></p>
<table cellSpacing=0 cellPadding=0 width=595 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=95>
            <p><span>atlcache.h</span></p>
            </td>
            <td vAlign=top width=144>
            <p><span>atlcrypt.h</span></p>
            </td>
            <td vAlign=top width=106>
            <p><span>atlcrypt.inl</span></p>
            </td>
            <td vAlign=top width=126>
            <p><span>atlextmgmt.h</span></p>
            </td>
            <td vAlign=top width=124>
            <p><span>atlhtml.h</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=95>
            <p><span>atlhttp.h</span></p>
            </td>
            <td vAlign=top width=144>
            <p><span>atlhttp.inl</span></p>
            </td>
            <td vAlign=top width=106>
            <p><span>atlisapi.h</span></p>
            </td>
            <td vAlign=top width=126>
            <p><span>atlmime.h</span></p>
            </td>
            <td vAlign=top width=124>
            <p><span>atlperf.h</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=95>
            <p><span>atlperf.inl</span></p>
            </td>
            <td vAlign=top width=144>
            <p><span>atlrx.h</span></p>
            </td>
            <td vAlign=top width=106>
            <p><span>atlsession.h</span></p>
            </td>
            <td vAlign=top width=126>
            <p><span>atlserr.h</span></p>
            </td>
            <td vAlign=top width=124>
            <p><span>atlsharedsvc.h</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=95>
            <p><span>atlsiface.h</span></p>
            </td>
            <td vAlign=top width=144>
            <p><span>atlsmtpconnection.h</span></p>
            </td>
            <td vAlign=top width=106>
            <p><span>atlsmtputil.h</span></p>
            </td>
            <td vAlign=top width=126>
            <p><span>atlsoap.h</span></p>
            </td>
            <td vAlign=top width=124>
            <p><span>atlsrv.rc</span></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=95>
            <p><span>atlsrvres.h</span></p>
            </td>
            <td vAlign=top width=144>
            <p><span>atlstencil.h</span></p>
            </td>
            <td vAlign=top width=106>
            <p><span>res\dllmgr.srf</span></p>
            </td>
            <td vAlign=top width=126>
            <p><span>res\stencilmgr.srf</span></p>
            </td>
            <td vAlign=top width=124>
            <p><span>res\threadmgr.srf</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><span>下面这些工具的源码也将会公开。</span></p>
<p><span><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span><span>&nbsp;&nbsp;&nbsp; </span></span><span>clstencil.exe - used in running Request Handler DLLs or SRF Files from the command line</span><span> </span></p>
<p><span><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>sproxy.exe - used in generating proxy classes for SOAP based Web Service clients</span><span> </span><span>（用来生成</span><span>WEB Service</span><span>的代理。以便于编程调用）</span></p>
<p><span><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>vcdeploy.exe - used in deploying ATL Server projects to IIS</span><span> <br><br>今天，有点时间在看ATL server方面的资料。打开前面说的网站，并找到了这些东东，实不敢独享。<a href="http://atlserver.codeplex.com/">http://atlserver.codeplex.com/</a>这里有我前面说的头文件与工具。</span></p>
<img src ="http://www.cppblog.com/Robertxiao/aggbug/85845.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Robertxiao/" target="_blank">Robertxiao</a> 2009-05-26 22:39 <a href="http://www.cppblog.com/Robertxiao/archive/2009/05/26/85845.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CComPtr&lt;T&gt;的构造函数与 Attach方法的使用</title><link>http://www.cppblog.com/Robertxiao/archive/2008/10/21/64622.html</link><dc:creator>Robertxiao</dc:creator><author>Robertxiao</author><pubDate>Tue, 21 Oct 2008 08:52:00 GMT</pubDate><guid>http://www.cppblog.com/Robertxiao/archive/2008/10/21/64622.html</guid><wfw:comment>http://www.cppblog.com/Robertxiao/comments/64622.html</wfw:comment><comments>http://www.cppblog.com/Robertxiao/archive/2008/10/21/64622.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Robertxiao/comments/commentRss/64622.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Robertxiao/services/trackbacks/64622.html</trackback:ping><description><![CDATA[&nbsp;
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CComPtr&lt;T&gt;是一个ATL中的一个智能指针类型，它及它的派生类CComQIPtr&lt;T&gt;为我们提供了智能管理COM接口指针的能力。 也就是在析构时自动释放资源的工具类，这些工具类能有效地帮助我们杜绝内存泄漏、句柄没有释放之类错误。她们是很智能、很聪明，不过这要我们写出正确的程式，如果使用不正确也会出现上述这些问题。往往内存泄漏、句柄没有释放这些错误很难一下调试出来，多数是通过工具来检查出来。有的工具对智能指针的误用也是较难发现。</p>
下面是我经历过的一个场景：<br>&nbsp;
<p>[</p>
<p>object,</p>
<p>uuid(&#8230;.),</p>
<p>&#8230;.</p>
<p>]</p>
<p>Interface IA</p>
<p>{</p>
<p>&#8230;</p>
<p>};</p>
<p>&nbsp;</p>
<p>//Client;</p>
<p>Class B</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IA GetIA(..);</p>
<p>};</p>
<p>B b;</p>
<p>CComPtr&lt;IA&gt; aPtr(b.GetIA(&#8230;));</p>
<p>&nbsp;</p>
<p>这样导致我的一个结构化存储资源被长久地占用，不能删除。有人或许已经知道问题的所在了。这个错误就在于CComPtr&lt;IA&gt; aPtr(b.GetIA(&#8230;));这样从方法传出来的接口就没有能够调用Release，这样泄漏就产生了。正确的使用应如下</p>
<p>&nbsp;</p>
<p style="COLOR: #3366ff">CComPtr&lt;IA&gt; aPtr；</p>
<p><span style="COLOR: #3366ff">aPtr.Attach(b.GetIA(&#8230;));</span></p>
<p>&nbsp;</p>
<p>拿出这两个方法的源代码就非常清楚了。</p>
<p align=left>&nbsp;&nbsp;&nbsp;&nbsp; CComPtrBase(_In_opt_ T* lp) throw()</p>
<p align=left>&nbsp;&nbsp;&nbsp;&nbsp; {</p>
<p align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p = lp;</p>
<p align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (p != NULL)</p>
<p align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p-&gt;AddRef();</p>
<p align=left>&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p align=left>&nbsp;</p>
<p align=left>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; void Attach(_In_opt_ T* p2) throw()</p>
<p align=left>&nbsp;&nbsp;&nbsp;&nbsp; {</p>
<p align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (p)</p>
<p align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p-&gt;Release();</p>
<p align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p = p2;</p>
<p align=left>&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p align=left>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;对于Detach和析构方法不会因混乱造成问题，因为Detach总是用于一个方法中要返回一个智能指针的实际接口时调用从而达到使代码简洁。而析构也会因为分离出了接口指针而不做任何事情。</p>
<img src ="http://www.cppblog.com/Robertxiao/aggbug/64622.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Robertxiao/" target="_blank">Robertxiao</a> 2008-10-21 16:52 <a href="http://www.cppblog.com/Robertxiao/archive/2008/10/21/64622.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ATL中集合和枚举器的编写</title><link>http://www.cppblog.com/Robertxiao/archive/2008/10/05/63275.html</link><dc:creator>Robertxiao</dc:creator><author>Robertxiao</author><pubDate>Sun, 05 Oct 2008 08:07:00 GMT</pubDate><guid>http://www.cppblog.com/Robertxiao/archive/2008/10/05/63275.html</guid><wfw:comment>http://www.cppblog.com/Robertxiao/comments/63275.html</wfw:comment><comments>http://www.cppblog.com/Robertxiao/archive/2008/10/05/63275.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Robertxiao/comments/commentRss/63275.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Robertxiao/services/trackbacks/63275.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;许多COM库都是一组对象的形式暴露给外界使用，这组对象通常被称作对象模型。这组对象模型中通常有父对象或者说是根对象，这个对象是允许被创建的，这个根对象有子对象或子对象的集合，这些个子对象不能自主创建他必须被他的根对象创建或者是被他的父对象创建。举个例子来说可能会更加清晰：比如microsoft outlook对象模型。这个对象模型有个一个根对象是Application，这个对象允许我们用CoCreateInstance来创建，这个COM对象下有一个称作Namespace的对象，Namespace对象下又有Store这样的对象，store对象下又有文件夹的集合，这些文件夹中又含有邮件或者是联系人等资料的集合，这个集合中的元素下又含有附件集合，如此便构成一个象金字塔式的分层体系。这些子对象常是在父对象中创建，不能象根对象一样呼叫CoCreateInstance等来创建。还有一个更加普通的例子便是MSXML的DOM模型，这个更为大家所熟知。在这些个模型中集合和枚举器在其中起到了粘合剂的作用。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下面我就对工作中写的枚举器过程进行一个简单回顾，我要实现一个指定范围内的偶数枚举器。这个简单的逻辑能让我很快地完成回顾，我可以花很少时间关注别的问题，花更多时间来关注实现过程。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;用向导生成ATL项目就叫MyCollection。在这个项目中加入一个Simple Atl Object类，名称就叫EvenNumbers。这样就在我们项目中MyCollection.idl文件中产生了相应的接口声明。为接口添加如下的方法或者属性<br><br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;MyCollection.idl&nbsp;:&nbsp;MyCollection&nbsp;的&nbsp;IDL&nbsp;源<br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #008000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #008000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #008000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;此文件将由&nbsp;MIDL&nbsp;工具处理以<br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #008000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;产生类型库(MyCollection.tlb)和封送处理代码。</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #008000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>import&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">oaidl.idl</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>import&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">ocidl.idl</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>[<br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">object</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;uuid(D4C7CD02</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">CD9F</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">48A6</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">BD6C</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">F1B02E66DA1C),<br></span><span style="COLOR: #008080">13</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;dual,<br></span><span style="COLOR: #008080">14</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;nonextensible,<br></span><span style="COLOR: #008080">15</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;helpstring(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">IEvenNumbers&nbsp;接口</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">),<br></span><span style="COLOR: #008080">16</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pointer_default(unique)<br></span><span style="COLOR: #008080">17</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>]<br></span><span style="COLOR: #008080">18</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000">&nbsp;IEvenNumbers&nbsp;:&nbsp;IDispatch<br></span><span style="COLOR: #008080">19</span><span style="COLOR: #000000"><img id=Codehighlighter1_317_595_Open_Image onclick="this.style.display='none'; Codehighlighter1_317_595_Open_Text.style.display='none'; Codehighlighter1_317_595_Closed_Image.style.display='inline'; Codehighlighter1_317_595_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_317_595_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_317_595_Closed_Text.style.display='none'; Codehighlighter1_317_595_Open_Image.style.display='inline'; Codehighlighter1_317_595_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_317_595_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_317_595_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">20</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;[id(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)]&nbsp;HRESULT&nbsp;Calc([</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">]&nbsp;LONG&nbsp;lMin,&nbsp;[</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">]&nbsp;LONG&nbsp;lMax);<br></span><span style="COLOR: #008080">21</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;[propget,&nbsp;id(</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)]&nbsp;HRESULT&nbsp;Count([</span><span style="COLOR: #0000ff">out</span><span style="COLOR: #000000">,&nbsp;retval]&nbsp;LONG</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pVal);<br></span><span style="COLOR: #008080">22</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;[propget,&nbsp;id(DISPID_VALUE)]&nbsp;HRESULT&nbsp;Item(LONG&nbsp;nIndex,&nbsp;[</span><span style="COLOR: #0000ff">out</span><span style="COLOR: #000000">,&nbsp;retval]&nbsp;LONG</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pVal);<br></span><span style="COLOR: #008080">23</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;[propget,&nbsp;id(DISPID_NEWENUM)]&nbsp;HRESULT&nbsp;_NewEnum([</span><span style="COLOR: #0000ff">out</span><span style="COLOR: #000000">,&nbsp;retval]&nbsp;IUnknown</span><span style="COLOR: #000000">**</span><span style="COLOR: #000000">&nbsp;pVal);<br></span><span style="COLOR: #008080">24</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">25</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>[<br></span><span style="COLOR: #008080">26</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;uuid(FFFC1807</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">CFBA</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">47A0</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">9036</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">04AC92E02F8D),<br></span><span style="COLOR: #008080">27</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;version(</span><span style="COLOR: #000000">1.0</span><span style="COLOR: #000000">),<br></span><span style="COLOR: #008080">28</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;helpstring(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MyCollection&nbsp;1.0&nbsp;类型库</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">29</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>]<br></span><span style="COLOR: #008080">30</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>library&nbsp;MyCollectionLib<br></span><span style="COLOR: #008080">31</span><span style="COLOR: #000000"><img id=Codehighlighter1_722_901_Open_Image onclick="this.style.display='none'; Codehighlighter1_722_901_Open_Text.style.display='none'; Codehighlighter1_722_901_Closed_Image.style.display='inline'; Codehighlighter1_722_901_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_722_901_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_722_901_Closed_Text.style.display='none'; Codehighlighter1_722_901_Open_Image.style.display='inline'; Codehighlighter1_722_901_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_722_901_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_722_901_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">32</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;importlib(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">stdole2.tlb</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">33</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;[<br></span><span style="COLOR: #008080">34</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uuid(503BB40F</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">86C8</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">4D1A</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">8E5C</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">5C81460C3EA5),<br></span><span style="COLOR: #008080">35</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;helpstring(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">EvenNumbers&nbsp;Class</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">36</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;]<br></span><span style="COLOR: #008080">37</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;coclass&nbsp;EvenNumbers<br></span><span style="COLOR: #008080">38</span><span style="COLOR: #000000"><img id=Codehighlighter1_859_898_Open_Image onclick="this.style.display='none'; Codehighlighter1_859_898_Open_Text.style.display='none'; Codehighlighter1_859_898_Closed_Image.style.display='inline'; Codehighlighter1_859_898_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_859_898_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_859_898_Closed_Text.style.display='none'; Codehighlighter1_859_898_Open_Image.style.display='inline'; Codehighlighter1_859_898_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_859_898_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_859_898_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">39</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style="COLOR: #0000ff">default</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000">&nbsp;IEvenNumbers;<br></span><span style="COLOR: #008080">40</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">41</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">42</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;现在我们完成了大部分的工作，就留下较难的get__NewEnum实现。在理解实现机理后这部分也不算难，这里只是回顾一个写作过程，并不会太多地说原理，跟着做就可以实现一般应用要求的集合枚举器。不说原理的原因是ATL很复杂，自己水平又有限。有人说MFC库是个魔鬼，我认为ATL库的复杂度也不会比MFC库容易。ATL库对C++中的模板应用可以说发挥到了极致。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EvenNumbers.h文件。</p>
<span id=Codehighlighter1_1065_1067_Open_Text>
<p></span>&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">vector</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Reuse/VCUE_CopyLong.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MyCollection_i.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;LongColl<br><img id=Codehighlighter1_98_772_Open_Image onclick="this.style.display='none'; Codehighlighter1_98_772_Open_Text.style.display='none'; Codehighlighter1_98_772_Closed_Image.style.display='inline'; Codehighlighter1_98_772_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_98_772_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_98_772_Closed_Text.style.display='none'; Codehighlighter1_98_772_Open_Image.style.display='inline'; Codehighlighter1_98_772_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_98_772_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_98_772_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;std::vector</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">LONG</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ContainerType;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;VARIANT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EnumeratorExposedType;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;IEnumVARIANT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EnumeratorInterface;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;LONG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CollectionExposedType;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;IEvenNumbers&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CollectionInterface;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;VCUE::GenericCopy</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">EnumeratorExposedType,&nbsp;ContainerType::value_type</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;EnumeratorCopyType;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;_Copy</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">CollectionExposedType</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;CollectionCopyType;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;CComEnumOnSTL</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">EnumeratorInterface,</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">__uuidof(EnumeratorInterface),&nbsp;EnumeratorExposedType,&nbsp;EnumeratorCopyType,&nbsp;ContainerType</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;EnumeratorType;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;ICollectionOnSTLImpl</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">CollectionInterface,&nbsp;ContainerType,&nbsp;CollectionExposedType,&nbsp;CollectionCopyType,&nbsp;EnumeratorType</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;CollectionType;<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: #008000">//</span><span style="COLOR: #008000">&nbsp;CEvenNumbers</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;ATL_NO_VTABLE&nbsp;CEvenNumbers&nbsp;:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;CComObjectRootEx</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">CComSingleThreadModel</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;CComCoClass</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">CEvenNumbers,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">CLSID_EvenNumbers</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">,<br><img id=Codehighlighter1_1021_1032_Open_Image onclick="this.style.display='none'; Codehighlighter1_1021_1032_Open_Text.style.display='none'; Codehighlighter1_1021_1032_Closed_Image.style.display='inline'; Codehighlighter1_1021_1032_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_1021_1032_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1021_1032_Closed_Text.style.display='none'; Codehighlighter1_1021_1032_Open_Image.style.display='inline'; Codehighlighter1_1021_1032_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;IDispatchImpl</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">LongColl::CollectionType,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">IID_IEvenNumbers,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">LIBID_MyCollectionLib,&nbsp;</span><span id=Codehighlighter1_1021_1032_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_1021_1032_Open_Text><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">wMajor&nbsp;=</span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;</span><span id=Codehighlighter1_1037_1048_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_1037_1048_Open_Text><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">wMinor&nbsp;=</span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img id=Codehighlighter1_1053_1055_Open_Image onclick="this.style.display='none'; Codehighlighter1_1053_1055_Open_Text.style.display='none'; Codehighlighter1_1053_1055_Closed_Image.style.display='inline'; Codehighlighter1_1053_1055_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_1053_1055_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1053_1055_Closed_Text.style.display='none'; Codehighlighter1_1053_1055_Open_Image.style.display='inline'; Codehighlighter1_1053_1055_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_1053_1055_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_1053_1055_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span></div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;由于我们的类继承了ICollectionImpl，所以Item, Count这两个属性我们可以不必自己再去实现。我们只要实现Calc方法 及_NewEnum属性了。这里使用ATL开发小组提供的文件VCUE_Collection。所以只需一行代码就解决这个问题。如下：<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: #000000">STDMETHODIMP&nbsp;CEvenNumbers::Calc(LONG&nbsp;lMin,&nbsp;LONG&nbsp;lMax)<br><img id=Codehighlighter1_54_194_Open_Image onclick="this.style.display='none'; Codehighlighter1_54_194_Open_Text.style.display='none'; Codehighlighter1_54_194_Closed_Image.style.display='inline'; Codehighlighter1_54_194_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_54_194_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_54_194_Closed_Text.style.display='none'; Codehighlighter1_54_194_Open_Image.style.display='inline'; Codehighlighter1_54_194_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_54_194_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_54_194_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;TODO:&nbsp;在此添加实现代码</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;((lMin&nbsp;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)<br><img id=Codehighlighter1_98_111_Open_Image onclick="this.style.display='none'; Codehighlighter1_98_111_Open_Text.style.display='none'; Codehighlighter1_98_111_Closed_Image.style.display='inline'; Codehighlighter1_98_111_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_98_111_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_98_111_Closed_Text.style.display='none'; Codehighlighter1_98_111_Open_Image.style.display='inline'; Codehighlighter1_98_111_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_98_111_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_98_111_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">lMin;<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;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(LONG&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;lMin;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;lMax;&nbsp;i&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)<br><img id=Codehighlighter1_153_178_Open_Image onclick="this.style.display='none'; Codehighlighter1_153_178_Open_Text.style.display='none'; Codehighlighter1_153_178_Closed_Image.style.display='inline'; Codehighlighter1_153_178_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_153_178_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_153_178_Closed_Text.style.display='none'; Codehighlighter1_153_178_Open_Image.style.display='inline'; Codehighlighter1_153_178_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_153_178_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_153_178_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;m_vec.push_back(i);<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;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;S_OK;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p></span>&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">STDMETHODIMP&nbsp;CEvenNumbers::get__NewEnum(IUnknown</span><span style="COLOR: #000000">**</span><span style="COLOR: #000000">&nbsp;pVal)<br><img id=Codehighlighter1_57_158_Open_Image onclick="this.style.display='none'; Codehighlighter1_57_158_Open_Text.style.display='none'; Codehighlighter1_57_158_Closed_Image.style.display='inline'; Codehighlighter1_57_158_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_57_158_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_57_158_Closed_Text.style.display='none'; Codehighlighter1_57_158_Open_Image.style.display='inline'; Codehighlighter1_57_158_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_57_158_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_57_158_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;TODO:&nbsp;在此添加实现代码</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;VCUE::CreateSTLEnumerator</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">LongColl::EnumeratorType</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">(pVal,&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">,&nbsp;m_vec);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;到此就做好一个集合枚举器的例子。可以在C#中使用。如下。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach(object obj in evenNumbers)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp; Console.WriteLine(obj.ToString()); }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sample:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.cppblog.com/Files/Robertxiao/MyCollection.rar">http://www.cppblog.com/Files/Robertxiao/MyCollection.rar</a> </p>
<img src ="http://www.cppblog.com/Robertxiao/aggbug/63275.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Robertxiao/" target="_blank">Robertxiao</a> 2008-10-05 16:07 <a href="http://www.cppblog.com/Robertxiao/archive/2008/10/05/63275.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ATL连接点开发总结</title><link>http://www.cppblog.com/Robertxiao/archive/2008/09/30/63084.html</link><dc:creator>Robertxiao</dc:creator><author>Robertxiao</author><pubDate>Tue, 30 Sep 2008 08:01:00 GMT</pubDate><guid>http://www.cppblog.com/Robertxiao/archive/2008/09/30/63084.html</guid><wfw:comment>http://www.cppblog.com/Robertxiao/comments/63084.html</wfw:comment><comments>http://www.cppblog.com/Robertxiao/archive/2008/09/30/63084.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Robertxiao/comments/commentRss/63084.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Robertxiao/services/trackbacks/63084.html</trackback:ping><description><![CDATA[&nbsp;
<p><span style="FONT-SIZE: 18pt">连接点语义<br></p>
<p><br></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>第一种说法</span><span>:</span><span>是一种逻辑上的反馈机制</span><span>,</span><span>这种机制允许对象暴露其</span><span>&#8221;</span><span>调用一个或者多个指定接口的能力</span><span>&#8221;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>第二种说法</span><span>:QueryInterface</span><span>允许客户从对象中取得一个指向对象实现的接口指针</span><span>,</span><span>连接点允许客户给予对象一个由客户实现的接口指针</span><span>.</span></p>
<p><span>在这种情形下</span><span>:COM</span><span>对象是源</span><span>,</span><span>客户提供的方法是接收器</span><span>.</span></p>
<p><span>源必须实现</span><span>IConnectionPoint</span></p>
<p>&nbsp;</p>
<p><span>Interface IConnectionPoint</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HRESULT GetConnectionInterface([out] IID *pIID);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HRESULT GetConnectionPointContainer([out] IConnectionPointContainer** ppCPC);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HRESULT Advise([in] IUnknnown *punkSing, [Out] DWORD *pdwCookie);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HRESULT Unadvise([in]DWORD dwCookie);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HREUSLT EnumConnections([out] IEnumConnections** ppEnum);</span></p>
<p><span>}</span></p>
<p>&nbsp;</p>
<p><span>Interface IConnectionPointContainer</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HRESULT EnumConnectionPoints([out] IEnumConnectionPoints **ppEnum);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HRESULT FindConnectionPoint([in] REFIID riid, [out] IConnectionPoint **ppcP);</span></p>
<p><span>}</span></p>
<p>&nbsp;</p>
<p><span>客户的使用方法</span><span>:</span></p>
<p><span>IUnKnown *pSource;</span></p>
<p><span>ISpeakerEvent *pSink;</span></p>
<p><span>DWORD dwCookie;</span></p>
<p><span>IConnectionPointContainer pcpc;</span></p>
<p><span>Hr = pSource-&gt;QueryInterface(&amp;pcpc);</span></p>
<p><span>IConnectionPoint pcp;</span></p>
<p><span>Hr = pcpc-&gt;FindConnection(__uuidof(ISpeakerEvent));</span></p>
<p><span>Hr = pcp-&gt;Advise(pSink,&amp;dwCookie);</span></p>
<p><span>Hr = pcp-&gt;Unadvise(dwCookie);</span></p>
<p><span>便捷的的宏</span><span>:</span></p>
<p><span>AtlAdivse(psource, pSink, __uuidof(ISpeakerEvent), &amp;dwCookie);</span></p>
<p><span>AtlUnadvise(psource, __uuidof(ISpeakerEvent), dwCookie);</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span>建立可连接对象的步聚</span><span>:</span></p>
<p><span>1:</span><span>实现</span><span>IConnectionPointContainer</span><span>接口</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Class ATL_NO_VTABLE className:</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&#8230;.</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public IConnectionPointContainerImpl&lt;className&gt;</span></p>
<p><span>{&#8230;..</span></p>
<p><span>};</span></p>
<p><span>2:QueryInterface</span><span>对</span><span>DIID_IConnectionPointContainer</span><span>的请求作出响应</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>BEGIN_COM_MAP</span></p>
<p><span>&#8230;</span></p>
<p><span>COM_INTERFACE_ENTRY(IConnectionPointContainer)</span></p>
<p><span>END_COM_MAP</span></p>
<p>&nbsp;</p>
<p><span>3:</span><span>我们要为每个可连接对象支持的源接口实现</span><span>IConnectionPoint</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Class ATL_NO_VTABLE className:</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&#8230;.</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public IConnectionPointContainerImpl&lt;className&gt;,</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public IConnectionPointImpl&lt;className, &amp;DIID__</span><span>对外的接口</span><span>&gt;</span></p>
<p><span>{&#8230;..</span></p>
<p><span>};</span></p>
<p><span>4:</span><span>我们要提供一个连接映射表</span><span>,</span><span>也就是一个</span><span>IID</span><span>和连接点实现联系起来的表</span><span>.</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>BEGIN_CONNECTION_POINT_MAP</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>CONNECTION_POINT_MAP_ENTRY(DIID__</span><span>对外的接口</span><span>)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&#8230;.</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>END_CONNECTION_POINT_MAP()</span></p>
<p>&nbsp;</p>
<p><span>5:</span><span>我们必须更新可连接对象在</span><span>IDL</span><span>文件中</span><span>coClass</span><span>的定义</span><span>,</span><span>以便指定每个源接口</span><span>.</span><span>每个源接口必须具有属性</span><span>,</span><span>主源接口应具有</span><span>[default, source]</span><span>属性</span><span>.</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Coclass </span><span>类厂名</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{&#8230;&#8230;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>[default,source] dispinterface _</span><span>对外接口</span><span>;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>};</span></p>
<p><span>6:</span><span>一般来说</span><span>,</span><span>我们希望通过辅助方法为所有连接的接收器调用接收器方法</span><span>.</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HRESULT Fire_</span><span>事件</span><span>(parameter)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>依次调用每个接收器的方法</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>可以使用</span><span>IDE</span><span>来生成连接点代理类</span><span>.</span><span>这样我们的源可以从其派生</span><span>,</span><span>而不再从</span><span>IConnectionPointImpl</span><span>派生</span><span>.</span></p>
<p><span>7:</span><span>我们必须在适当的时机调用辅助方法</span><span>.</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span>建立接收事件的对象</span><span>:</span></p>
<p><span>1:</span><span>实现事件接收器</span><span>.</span><span>可先的方案有从</span></p>
<p><span>IDispEventSimpleImpl&lt;UINT nID, class T, const IID *pdIID = &amp;IID_NULL&gt;</span></p>
<p><span>或者</span><span>:</span></p>
<p><span>IDispEventImpl&lt; UINT nID, class T, const IID *pdIID = &amp;IID_NULL, </span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Const GUID*plibid= &amp;GUID_NULL,</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DWORD wMajor = 0, WORD wMinor = 0,</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Class tihclass = CComTypeInfoHolder&gt;</span></p>
<p><span>派生</span><span>.</span></p>
<p><span><span>&nbsp;&nbsp; </span></span><span>例如</span><span>:</span></p>
<p><span><span>&nbsp;&nbsp; </span>static const int DEFSOURCEID = 1;</span></p>
<p><span><span>&nbsp;&nbsp; </span>class CEarPolitic;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>typedef IDispEventImpl&lt; DEFSOURCEID, CEarPolitic, &amp;DIID__ISpeackerEvents</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&amp;LIBID_ATLINTERNALSLIB, LIBMAJOR,LIBMINOR&gt; DefSource;</span></p>
<p><span>Class ATL_NO_VTABLE CEarPolitic</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>:public DefSource</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&#8230;.</span></p>
<p><span>}</span></p>
<p>&nbsp;</p>
<p><span>2:</span><span>事件接收器映射表</span></p>
<p><span>&nbsp;BEGIN_SINK_MAP(CEarPolitic)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>SINK_ENTRY_EX(source, DIID, DISPID, EventHandlerFunc)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>SINK_ENTRY_EX(source, DIID, DISPID, EventHandlerFunc, &amp;info)</span></p>
<p><span>&nbsp;END_SINK_MAP()</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>例如</span><span>:</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>void &nbsp;__stdcall OnHearPlaintiffWhisper(BSTR bstrText);//sink</span><span>接口的一个方法</span><span>.</span></p>
<p><span><span>&nbsp;&nbsp; </span></span></p>
<p><span>_ATL_FUNC_INFO OnHearPlaintiffWhisper = </span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{CC_STDCALL, VT_EMPTY, 1, { VT_BSTR}};</span></p>
<p><span>Static const int SOURCEID = 1;</span></p>
<p>&nbsp;</p>
<p><span>BEGIN_SINK_MAP(CEarPolitic)</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>SINK_ENTRY_EX(SOURCEID, DIID__</span><span>对外接口</span><span>, </span><span>方法的</span><span>DISPID, OnHearPlaintiffWhisper)</span></p>
<p><span>END_SINK_MAP()</span></p>
<p>&nbsp;</p>
<p><span>3:</span><span>进一步实现这个回调函数</span><span>.</span></p>
<p><span>4:</span><span>把事件接收器连接到数据源</span></p>
<p>&nbsp;</p>
<img src ="http://www.cppblog.com/Robertxiao/aggbug/63084.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Robertxiao/" target="_blank">Robertxiao</a> 2008-09-30 16:01 <a href="http://www.cppblog.com/Robertxiao/archive/2008/09/30/63084.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RPC 漫游&lt;1&gt;: 模型</title><link>http://www.cppblog.com/Robertxiao/archive/2007/11/16/36775.html</link><dc:creator>Robertxiao</dc:creator><author>Robertxiao</author><pubDate>Fri, 16 Nov 2007 14:11:00 GMT</pubDate><guid>http://www.cppblog.com/Robertxiao/archive/2007/11/16/36775.html</guid><wfw:comment>http://www.cppblog.com/Robertxiao/comments/36775.html</wfw:comment><comments>http://www.cppblog.com/Robertxiao/archive/2007/11/16/36775.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Robertxiao/comments/commentRss/36775.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Robertxiao/services/trackbacks/36775.html</trackback:ping><description><![CDATA[<p align=left>RPC:Remote Produce Call 是这几个单词的缩写。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们直译过来就是远程过程调用。对，这种技术是实现远端的过程调用，远端意味着跨主机、可能跨平台、跨网络、跨进程是毫无疑问的事情了，所以我们也可以使用RPC技术来实现本机上一个进程中方法调用另一个进程中的方法。使用这种技术客户机可以调用远端的服务器来执行工作，执行完后把结果集返回来。但是这种复杂性对用户来说是透明的，用户可以是系统的使用者，也可能是开发高层应用逻辑的开发员。<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RPC是怎么工作的呢？我就在下面做了个草图来表达一下。以一个Hello过程来描述。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Client&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; Server&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br><br>
<table style="WIDTH: 320px; BORDER-COLLAPSE: collapse" cellSpacing=0 cellPadding=3 border=1>
    <tbody>
        <tr borderColorDark=#000000>
            <td>
            <p>Hello</p>
            </td>
            <td></td>
            <td></td>
            <td></td>
            <td>Hello</td>
        </tr>
        <tr>
            <td>Client Stub</td>
            <td></td>
            <td></td>
            <td></td>
            <td>Server Stub</td>
        </tr>
        <tr>
            <td>Client Runtime Liberary</td>
            <td></td>
            <td></td>
            <td></td>
            <td>Server RuntimeLiberary</td>
        </tr>
        <tr>
            <td>Transport</td>
            <td></td>
            <td></td>
            <td></td>
            <td>Transport</td>
        </tr>
    </tbody>
</table>
<br>客户调用过程如下：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1：客户端应用程序在客户机发出方法调用Hello。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2：Client Stub接受应用程序的方法调用，并把请求、数据组织成标准格式给Client Runtime Liberary层。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3：Client Runtime Liberary通过指定的通道（可能是管理、网络等）发送数据及请求。<br><br>服务接收过程如下：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1：Server RuntimeLiberary负责实时地从网络接收数据、请求。把它交给Server Stub。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2：Server Stub 负责把数据译成本地格式并进一步调用应用程序实现的服务。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3：执行服务Hello.打印出"Hello World"&nbsp;。<br><br>服务端服务执行完后的返回过程：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1：服务把返回数据给Server Stub&nbsp;。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2：Server Stub&nbsp;把数据转换成标准格式给Server RuntimeLiberary。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3：Server RuntimeLiberary 则向客户方发送结果数据。<br><br>客户方的接受过程<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1：Client Runtime Liberary接受数据交给Client Runtime Liberary。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2：Client Runtime Liberary把标准格式的数据译成本机、本地语言（是开发语言）的数据。并进而交给客户程序。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3：客户程序收到服务端处理后的信息了。客户如何利用这个信息呢？哦！这是他的事...................<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RPC模型最初是由SUN公司提出来的，到在现在有多种RPC模型。我这里将要讨论的RPC知识是microsoft RPC模型。</p>
<img src ="http://www.cppblog.com/Robertxiao/aggbug/36775.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Robertxiao/" target="_blank">Robertxiao</a> 2007-11-16 22:11 <a href="http://www.cppblog.com/Robertxiao/archive/2007/11/16/36775.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>UUID 初识</title><link>http://www.cppblog.com/Robertxiao/archive/2007/11/10/36270.html</link><dc:creator>Robertxiao</dc:creator><author>Robertxiao</author><pubDate>Sat, 10 Nov 2007 02:45:00 GMT</pubDate><guid>http://www.cppblog.com/Robertxiao/archive/2007/11/10/36270.html</guid><wfw:comment>http://www.cppblog.com/Robertxiao/comments/36270.html</wfw:comment><comments>http://www.cppblog.com/Robertxiao/archive/2007/11/10/36270.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/Robertxiao/comments/commentRss/36270.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Robertxiao/services/trackbacks/36270.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UUID(Universal Unique Identifier)是这几单词的简写罢了，我们就译它全球唯一标识这个名称。它真的永远能唯一标识吗？它是如何生成的呢？生成的工具有哪些呢？是由何而来呢？下面我来谈一下我的认识。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;能永远唯一标识吗？对于这个问题。我们还是先来认识一下UUID，UUID其实就是一个字符串，它是一个有且仅有128位的字符串，也就是16个字节了，如uuid(c37c9ab7-9fc5-4ecb-9e9f-71ae06156f74)。它的表现形式（就是说写法）上有几种。表示的字符是0~f。共有32个这样的字符，那么32的16次方可供使用，所以肯定不能永远的唯一，随着发展肯定会有更好表示了。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 生成的工具有哪些呢？就Visual studio&nbsp;这个集成开发环境，它带了两个生成UUID的工具，一个是界面形式的，一个是CONSOLE形式的。可以VS安装目录下的BIN文件夹下找到这两个工具，GUIDGEN.exe这个带有界面形式的工具，它可以根据你的要求生成指定格式的UUID。还有一个UUIDGEN.exe这个是CONSOLE形式的生成工具，它可以直接输出UUID到一个文件中去。看看帮助都会用。这里不详述。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如何生成的呢？很多是根据计算机上的网卡地址（不同计算机上的网卡地址是唯一的），再根据生成的时间来产生的（这就本机上生成的GUID不会重复）。网卡地址占用48位，而时间标戳占用60位。或许有的生成UUID的计算机没有网卡，那就会用另一套算法来生成了。就上面介绍的这两个工具来说它们的生成都会调用COM库中的CoCreateGuid这个函数，这个函数最终又调用UuidCreate函数来生这个UUID标识串。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UUID最初是由OSF（开放软件基金会提出来的）当时也出于DCE的需求而定义。它是用来标识一个唯一的被调用者。<br>有关UUID的知识。<a href="http://www.cppblog.com/alantop/archive/2007/07/09/27726.html">http://www.cppblog.com/alantop/archive/2007/07/09/27726.html</a>这里也有介绍。
<img src ="http://www.cppblog.com/Robertxiao/aggbug/36270.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Robertxiao/" target="_blank">Robertxiao</a> 2007-11-10 10:45 <a href="http://www.cppblog.com/Robertxiao/archive/2007/11/10/36270.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>