﻿<?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++博客-股票数据格式转换软件 http://alantop.5166.info 公布股票数据格式文档 稳定盈利的外汇交易系统黑牛外汇交易系统 MT4编程-随笔分类-COM</title><link>http://www.cppblog.com/alantop/category/1620.html</link><description>股票数据格式转换软件 http://alantop.5166.info 公布股票数据格式文档 稳定盈利的外汇交易系统黑牛外汇交易系统 MT4编程</description><language>zh-cn</language><lastBuildDate>Tue, 20 May 2008 01:53:00 GMT</lastBuildDate><pubDate>Tue, 20 May 2008 01:53:00 GMT</pubDate><ttl>60</ttl><item><title>托管代码如何调用非托管代码(c sharp如何调用c++代码)?</title><link>http://www.cppblog.com/alantop/archive/2008/04/16/47318.html</link><dc:creator>AlanTop</dc:creator><author>AlanTop</author><pubDate>Wed, 16 Apr 2008 12:32:00 GMT</pubDate><guid>http://www.cppblog.com/alantop/archive/2008/04/16/47318.html</guid><wfw:comment>http://www.cppblog.com/alantop/comments/47318.html</wfw:comment><comments>http://www.cppblog.com/alantop/archive/2008/04/16/47318.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/alantop/comments/commentRss/47318.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alantop/services/trackbacks/47318.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 托管代码如何调用非托管代码(c sharp如何调用c++代码)?&nbsp;&nbsp;<a href='http://www.cppblog.com/alantop/archive/2008/04/16/47318.html'>阅读全文</a><img src ="http://www.cppblog.com/alantop/aggbug/47318.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alantop/" target="_blank">AlanTop</a> 2008-04-16 20:32 <a href="http://www.cppblog.com/alantop/archive/2008/04/16/47318.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>由浅入深，举例讲解RPC（一）</title><link>http://www.cppblog.com/alantop/archive/2007/07/09/27727.html</link><dc:creator>AlanTop</dc:creator><author>AlanTop</author><pubDate>Mon, 09 Jul 2007 04:41:00 GMT</pubDate><guid>http://www.cppblog.com/alantop/archive/2007/07/09/27727.html</guid><wfw:comment>http://www.cppblog.com/alantop/comments/27727.html</wfw:comment><comments>http://www.cppblog.com/alantop/archive/2007/07/09/27727.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/alantop/comments/commentRss/27727.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alantop/services/trackbacks/27727.html</trackback:ping><description><![CDATA[&nbsp;
<p><span>关于</span><span>RPC</span><span>的文章很多，但是系统讲解的很少。下面我将写一个系列报道。用代码和论述来把</span><span>rpc</span><span>来讲讲清楚。</span></p>
<p><span>这篇就是开始第一篇了。</span></p>
<p>&nbsp;</p>
<p><span>由于工作比较忙。我们抽出一个星期的时间，有时间会写一点。把这个系列写完。所以，有可能每个系列都比较短些。</span></p>
<p><span>从最基本的讲起，让大家彻底明白</span><span>RPC.</span></p>
<p>&nbsp;</p>
<p><span>好了废话不多说了。正是开始。</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span>首先，你要用</span><span>RPC</span><span>，必须先搞清楚什么是</span><span>IDL.</span></p>
<p>&nbsp;</p>
<p><span>Rpc</span><span>是什么？</span><span> </span></p>
<p><span><a href="http://www.cppblog.com/alantop/archive/2007/07/09/27717.html">http://www.cppblog.com/alantop/archive/2007/07/09/27717.html</a></span></p>
<p><span>IDL</span><span>是什么？</span></p>
<p><span><a href="http://www.cppblog.com/alantop/archive/2007/07/09/27725.html">http://www.cppblog.com/alantop/archive/2007/07/09/27725.html</a> </span></p>
<p>&nbsp;</p>
<p><span>下来，举个例子。怎么样把一个标准程序改成用</span><span>IDL</span><span>语言写的程序。</span></p>
<p>&nbsp;</p>
<p><span>这是一个标准程序。</span></p>
<table cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=568>
            <p><span>// File Standalone.cpp</span></p>
            <p><span>#include &lt;iostream&gt;</span></p>
            <p>&nbsp;</p>
            <p><span>// Future server function.</span></p>
            <p><span>void Output(const char* szOutput)</span></p>
            <p><span>{</span></p>
            <p><span><span>&nbsp;&nbsp; </span>std::cout &lt;&lt; szOutput &lt;&lt; std::endl;</span></p>
            <p><span>}</span></p>
            <p>&nbsp;</p>
            <p><span>int main()</span></p>
            <p><span>{</span></p>
            <p><span><span>&nbsp;&nbsp; </span>// Future client call.</span></p>
            <p><span><span>&nbsp;&nbsp; </span>Output("Hello Lonely World!");</span></p>
            <p><span>}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><span>下来看我们怎么把它改为一个标准</span><span>IDL</span><span>语言的程序</span></p>
<p><span>用</span><span>IDL</span><span>语言定义接口：</span></p>
<table cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=568>
            <p><span>// File Example1.idl</span></p>
            <p><span>[</span></p>
            <p><span><span>&nbsp;&nbsp; </span>// A unique identifier that distinguishes this</span></p>
            <p><span><span>&nbsp;&nbsp; </span>// interface from other interfaces.</span></p>
            <p><span><span>&nbsp;&nbsp; </span>uuid(00000001-EAF3-4A7A-A0F2-BCE4C30DA77E),</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>// This is version 1.0 of this interface.</span></p>
            <p><span><span>&nbsp;&nbsp; </span>version(1.0),</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>// This interface will use an implicit binding</span></p>
            <p><span><span>&nbsp;&nbsp; </span>// handle named hExample1Binding.</span></p>
            <p><span><span>&nbsp;&nbsp; </span>implicit_handle(handle_t hExample1Binding)</span></p>
            <p><span>]</span></p>
            <p><span>interface Example1 // The interface is named Example1</span></p>
            <p><span>{</span></p>
            <p><span><span>&nbsp;&nbsp; </span>// A function that takes a zero-terminated string.</span></p>
            <p><span><span>&nbsp;&nbsp; </span>void Output(</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>[in, string] const char* szOutput);</span></p>
            <p><span>}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span>上面这个文件是我们用</span><span>idl</span><span>语言定义的，我们定义了一个接口</span><span>Example1, </span><span>它带有</span><span>uuid</span><span>和</span><span>version. </span><span>这个接口里定义了一个函数</span><span>Output.</span></p>
<p>&nbsp;</p>
<p><span>UUID</span><span>是什么？</span></p>
<p><span><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> </span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span>接口的</span><span>implicit_handle</span><span>属性，我们后面再讨论。</span></p>
<p>&nbsp;</p>
<p><span>接下来干什么呢？</span></p>
<p><span>我们为了在程序中使用</span><span>idl</span><span>，必须通过通过编译器（</span><span>midl.exe</span><span>）把它翻译成客户代理和服务器存根，</span> <span>代理和存根将在后面被我们的编译器（</span><span>windows</span><span>平台下的</span><span>cl.exe</span><span>）所使用。</span></p>
<p>&nbsp;<br></p>
<p><img height=150 alt="" src="http://www.cppblog.com/images/cppblog_com/alantop/rpcintro1_2.gif" width=363 border=0></p>
<p>&nbsp;</p>
<p><span>改好的服务器端程序：</span></p>
<table cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=568>
            <p><span>// File Example1Server.cpp</span></p>
            <p><span>#include &lt;iostream&gt;</span></p>
            <p><span>#include "Example1.h"</span></p>
            <p>&nbsp;</p>
            <p><span>// Server function.</span></p>
            <p><span>void Output(const char* szOutput)</span></p>
            <p><span>{</span></p>
            <p><span><span>&nbsp;&nbsp; </span>std::cout &lt;&lt; szOutput &lt;&lt; std::endl;</span></p>
            <p><span>}</span></p>
            <p>&nbsp;</p>
            <p><span>int main()</span></p>
            <p><span>{</span></p>
            <p><span><span>&nbsp;&nbsp; </span>RPC_STATUS status;</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>// Uses the protocol combined with the endpoint for receiving</span></p>
            <p><span><span>&nbsp;&nbsp; </span>// remote procedure calls.</span></p>
            <p><span><span>&nbsp;&nbsp; </span>status = RpcServerUseProtseqEp(</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>reinterpret_cast&lt;unsigned char*&gt;("ncacn_ip_tcp"), // Use TCP/IP</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;&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; </span>// protocol.</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // Backlog queue length for TCP/IP.</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>reinterpret_cast&lt;unsigned char*&gt;("4747"), // TCP/IP port to use.</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NULL); // No security.</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>if (status)</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>exit(status);</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>// Registers the Example1 interface.</span></p>
            <p><span><span>&nbsp;&nbsp; </span>status = RpcServerRegisterIf(</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Example1_v1_0_s_ifspec, // Interface to register.</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NULL, // Use the MIDL generated entry-point vector.</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NULL); // Use the MIDL generated entry-point vector.</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>if (status)</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>exit(status);</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>// Start to listen for remote procedure</span></p>
            <p><span><span>&nbsp;&nbsp; </span>// calls for all registered interfaces.</span></p>
            <p><span><span>&nbsp;&nbsp; </span>// This call will not return until</span></p>
            <p><span><span>&nbsp;&nbsp; </span>// RpcMgmtStopServerListening is called.</span></p>
            <p><span><span>&nbsp;&nbsp; </span>status = RpcServerListen(</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>1, // Recommended minimum number of threads.</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>RPC_C_LISTEN_MAX_CALLS_DEFAULT, // Recommended </span></p>
            <p><span>&nbsp;<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>//maximum number of threads.</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>FALSE); // Start listening now.</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>if (status)</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>exit(status);</span></p>
            <p><span>}</span></p>
            <p>&nbsp;</p>
            <p><span>// Memory allocation function for RPC.</span></p>
            <p><span>// The runtime uses these two functions for allocating/deallocating</span></p>
            <p><span>// enough memory to pass the string to the server.</span></p>
            <p><span>void* __RPC_USER midl_user_allocate(size_t size)</span></p>
            <p><span>{</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span>return malloc(size);</span></p>
            <p><span>}</span></p>
            <p>&nbsp;</p>
            <p><span>// Memory deallocation function for RPC.</span></p>
            <p><span>void __RPC_USER midl_user_free(void* p)</span></p>
            <p><span>{</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span>free(p);</span></p>
            <p><span>}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><span>这是初始化，和注册接口的代码。</span></p>
<p>&nbsp;</p>
<p><span>现在看看怎么写客户端</span></p>
<table cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=568>
            <p><span>// File Example1Client.cpp</span></p>
            <p><span>#include &lt;iostream&gt;</span></p>
            <p><span>#include "Example1.h"</span></p>
            <p>&nbsp;</p>
            <p><span>int main()</span></p>
            <p><span>{</span></p>
            <p><span><span>&nbsp;&nbsp; </span>RPC_STATUS status;</span></p>
            <p><span><span>&nbsp;&nbsp; </span>unsigned char* szStringBinding = NULL;</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>// Creates a string binding handle.</span></p>
            <p><span><span>&nbsp;&nbsp; </span>// This function is nothing more than a printf.</span></p>
            <p><span><span>&nbsp;&nbsp; </span>// Connection is not done here.</span></p>
            <p><span><span>&nbsp;&nbsp; </span>status = RpcStringBindingCompose(</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NULL, // UUID to bind to.</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>reinterpret_cast&lt;unsigned char*&gt;("ncacn_ip_tcp"), // Use TCP/IP</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;&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; </span>// protocol.</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>reinterpret_cast&lt;unsigned char*&gt;("localhost"), // TCP/IP network</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;&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>// address to use.</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>reinterpret_cast&lt;unsigned char*&gt;("4747"), // TCP/IP port to use.</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NULL, // Protocol dependent network options to use.</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&amp;szStringBinding); // String binding output.</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>if (status)</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>exit(status);</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>// Validates the format of the string binding handle and converts</span></p>
            <p><span><span>&nbsp;&nbsp; </span>// it to a binding handle.</span></p>
            <p><span><span>&nbsp;&nbsp; </span>// Connection is not done here either.</span></p>
            <p><span><span>&nbsp;&nbsp; </span>status = RpcBindingFromStringBinding(</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>szStringBinding, // The string binding to validate.</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&amp;hExample1Binding); // Put the result in the implicit binding</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; </span>// handle defined in the IDL file.</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>if (status)</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>exit(status);</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>RpcTryExcept</span></p>
            <p><span><span>&nbsp;&nbsp; </span>{</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// Calls the RPC function. The hExample1Binding binding handle</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// is used implicitly.</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// Connection is done here.</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Output("Hello RPC World!");</span></p>
            <p><span><span>&nbsp;&nbsp; </span>}</span></p>
            <p><span><span>&nbsp;&nbsp; </span>RpcExcept(1)</span></p>
            <p><span><span>&nbsp;&nbsp; </span>{</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>std::cerr &lt;&lt; "Runtime reported exception " &lt;&lt; RpcExceptionCode()</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&lt;&lt; std::endl;</span></p>
            <p><span><span>&nbsp;&nbsp; </span>}</span></p>
            <p><span><span>&nbsp;&nbsp; </span>RpcEndExcept</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>// Free the memory allocated by a string.</span></p>
            <p><span><span>&nbsp;&nbsp; </span>status = RpcStringFree(</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&amp;szStringBinding); // String to be freed.</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>if (status)</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>exit(status);</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>// Releases binding handle resources and disconnects from the server.</span></p>
            <p><span><span>&nbsp;&nbsp; </span>status = RpcBindingFree(</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&amp;hExample1Binding); // Frees the implicit binding handle defined in</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; </span>// the IDL file.</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp; </span>if (status)</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>exit(status);</span></p>
            <p><span>}</span></p>
            <p>&nbsp;</p>
            <p><span>// Memory allocation function for RPC.</span></p>
            <p><span>// The runtime uses these two functions for allocating/deallocating</span></p>
            <p><span>// enough memory to pass the string to the server.</span></p>
            <p><span>void* __RPC_USER midl_user_allocate(size_t size)</span></p>
            <p><span>{</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span>return malloc(size);</span></p>
            <p><span>}</span></p>
            <p>&nbsp;</p>
            <p><span>// Memory deallocation function for RPC.</span></p>
            <p><span>void __RPC_USER midl_user_free(void* p)</span></p>
            <p><span>{</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span>free(p);</span></p>
            <p><span>}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<img src ="http://www.cppblog.com/alantop/aggbug/27727.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alantop/" target="_blank">AlanTop</a> 2007-07-09 12:41 <a href="http://www.cppblog.com/alantop/archive/2007/07/09/27727.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>UUID是什么？</title><link>http://www.cppblog.com/alantop/archive/2007/07/09/27726.html</link><dc:creator>AlanTop</dc:creator><author>AlanTop</author><pubDate>Mon, 09 Jul 2007 04:31:00 GMT</pubDate><guid>http://www.cppblog.com/alantop/archive/2007/07/09/27726.html</guid><wfw:comment>http://www.cppblog.com/alantop/comments/27726.html</wfw:comment><comments>http://www.cppblog.com/alantop/archive/2007/07/09/27726.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/alantop/comments/commentRss/27726.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alantop/services/trackbacks/27726.html</trackback:ping><description><![CDATA[<font face=宋体>UUID就是Universal Unique IDentifier的缩写，它是一个128位，16字节的值，并确保在时间和空间上唯一。<br>它是把硬件地址、时间以及随机数结合在一起，来确保其唯一性的。</font><br><font face=宋体>一般情况下，生成算法用计算机网卡的地址和一个60位的timestamp生成，时间是以100ns为时间间隔。</font><br><font face=宋体>例如，一台300PL 6862的计算机，主板集成的网卡的MAC地址为00-04-AC-2E-B7-DC，而UUID的最后六个字节也会是0004AC2EB7DC</font>
<img src ="http://www.cppblog.com/alantop/aggbug/27726.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alantop/" target="_blank">AlanTop</a> 2007-07-09 12:31 <a href="http://www.cppblog.com/alantop/archive/2007/07/09/27726.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IDL是什么？</title><link>http://www.cppblog.com/alantop/archive/2007/07/09/27725.html</link><dc:creator>AlanTop</dc:creator><author>AlanTop</author><pubDate>Mon, 09 Jul 2007 04:22:00 GMT</pubDate><guid>http://www.cppblog.com/alantop/archive/2007/07/09/27725.html</guid><wfw:comment>http://www.cppblog.com/alantop/comments/27725.html</wfw:comment><comments>http://www.cppblog.com/alantop/archive/2007/07/09/27725.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/alantop/comments/commentRss/27725.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alantop/services/trackbacks/27725.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: IDL(Interface Definition Language)即接口定义语言。&nbsp;&nbsp;<a href='http://www.cppblog.com/alantop/archive/2007/07/09/27725.html'>阅读全文</a><img src ="http://www.cppblog.com/alantop/aggbug/27725.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alantop/" target="_blank">AlanTop</a> 2007-07-09 12:22 <a href="http://www.cppblog.com/alantop/archive/2007/07/09/27725.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>retval释疑</title><link>http://www.cppblog.com/alantop/archive/2006/11/11/14996.html</link><dc:creator>AlanTop</dc:creator><author>AlanTop</author><pubDate>Sat, 11 Nov 2006 01:07:00 GMT</pubDate><guid>http://www.cppblog.com/alantop/archive/2006/11/11/14996.html</guid><wfw:comment>http://www.cppblog.com/alantop/comments/14996.html</wfw:comment><comments>http://www.cppblog.com/alantop/archive/2006/11/11/14996.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/alantop/comments/commentRss/14996.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alantop/services/trackbacks/14996.html</trackback:ping><description><![CDATA[
		<p>为了让方法返回一个与''<u><b>方法的物理HRESULT</b></u>''不相关的逻辑结果，COM IDL支持retval参数属性。retval属性的含义是，<u><b>相关联的物理方法参数实际上是操作的逻辑结果，在支持retval的环境中，该参数应该被映射为操作的结果</b></u>。例如，给定下面的IDL方法定义：<br /><br /></p>
		<pre>HRESULT Method2( [in] short arg1,[out,retval] short * parg2);<br /><br />在Java语言中，应该被映射为下面的函数：<br />public short Method2(short arg1);<br />而在Visual Basic中，方法定义如下;<br />Function Method2(arg1 as Integer) as Integer<br /><br /><br />因为C++没有专门的运行时库来支持COM接口访问操作，所以Microsoft C++把这个方法映射程下面的函数：<br /></pre>
		<pre>virtual HRESULT __stdcall Method2(short arg1,short* parg2 ) = 0;<br /><br />//<br />// interface IVAIS wrapper method implementations<br />//</pre>
		<p>inline char IVAIS::ExecVerifyAIS ( _bstr_t AisContent, short length ) {<br />    char _result;<br />    HRESULT _hr = raw_ExecVerifyAIS(AisContent, length, &amp;_result);<br />    if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));<br />    return _result;<br />}<br /><br /></p>
<img src ="http://www.cppblog.com/alantop/aggbug/14996.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alantop/" target="_blank">AlanTop</a> 2006-11-11 09:07 <a href="http://www.cppblog.com/alantop/archive/2006/11/11/14996.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>com中用bool类型。</title><link>http://www.cppblog.com/alantop/archive/2006/11/10/14937.html</link><dc:creator>AlanTop</dc:creator><author>AlanTop</author><pubDate>Thu, 09 Nov 2006 23:36:00 GMT</pubDate><guid>http://www.cppblog.com/alantop/archive/2006/11/10/14937.html</guid><wfw:comment>http://www.cppblog.com/alantop/comments/14937.html</wfw:comment><comments>http://www.cppblog.com/alantop/archive/2006/11/10/14937.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/alantop/comments/commentRss/14937.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alantop/services/trackbacks/14937.html</trackback:ping><description><![CDATA[在com用用bool类型，还是有些讲究。<br />1. 如果你只是给c++或java使用，可以用boolean.其他语言不支持。<br />2. 你要是提高自动化变量VARIANT_BOOL,他的类型值是VARIANT_TRUE或者VARIANT_FALSE.<br /><br />com中可以自定义HRESULT的值。<br />一般用S_OK，表示函数调用成功。<br />用E_UNEXPECTED 表示的是代码中的错误。<br /><br /><img src ="http://www.cppblog.com/alantop/aggbug/14937.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alantop/" target="_blank">AlanTop</a> 2006-11-10 07:36 <a href="http://www.cppblog.com/alantop/archive/2006/11/10/14937.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>再次，解释CComPtr和CComQIPtr。</title><link>http://www.cppblog.com/alantop/archive/2006/05/13/7051.html</link><dc:creator>AlanTop</dc:creator><author>AlanTop</author><pubDate>Fri, 12 May 2006 19:44:00 GMT</pubDate><guid>http://www.cppblog.com/alantop/archive/2006/05/13/7051.html</guid><wfw:comment>http://www.cppblog.com/alantop/comments/7051.html</wfw:comment><comments>http://www.cppblog.com/alantop/archive/2006/05/13/7051.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/alantop/comments/commentRss/7051.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alantop/services/trackbacks/7051.html</trackback:ping><description><![CDATA[
		<p>
				<font face="Courier New" size="2">对于操作原始的接口指针是比较麻烦的，需要我们自己控制引用记数、API 调用、异常处理。于是 ATL 提供了2个智能指针的模板包装类，CComPtr&lt;&gt; 和 CComQIPtr&lt;&gt;，这两个类都在 &lt;atlbase.h&gt; 中声明。CComQIPtr&lt;&gt; 包含了 CComPtr&lt;&gt;的所有功能，因此我们可以完全用 CComQIPtr&lt;&gt; 来使用智能接口指针，唯一要说明的一点就是：CComQIPtr&lt;&gt; 由于使用了运算符的重载功能，它会自动帮我们调用QueryInterface()函数，因此 CComQIPtr&lt;&gt; 唯一的缺点就是不能定义 IUnknown * 指针。 <br /><br />     // 智能指针 smart pointer，按照匈牙利命名法，一般以 sp 开头来表示变量类型<br />　　  CComPtr &lt; IUnknown &gt; spUnk; // 正确<br />　　  // 假设 IFun 是一个接口类型<br />　　  CComPtr &lt; IFun &gt; spFun; // 正确<br />　　  CComQIPtr &lt; IFun &gt; spFun; // 正确<br />　　  CComQIPtr &lt; IFun, &amp;IID_IFun &gt; spFun; // 正确<br />　　  CComQIPtr &lt; IUnknown &gt; spUnk; // 错误！CComQIPtr不能定义IUnknown指针<br />  <br />给智能指针赋值的方法： <br />　　  CComQIPtr &lt; IFun &gt; spFun; // 调用构造函数，还没有赋值，被包装的内部接口指针为 NULL<br />　　  <br />　　  CComQIPtr &lt; IFun &gt; spFun( pOtherInterface ); // 调用构造函数，内部接口指针赋值为<br />　　  // 通过 pOtherInterface 这个普通接口指针调用QueryInterface()得到的IFun接口指针<br />　　  <br />　　  CComQIPtr &lt; IFun &gt; spFun( spOtherInterface ); // 调用构造函数，内部接口指针赋值为<br />　　  // 通过 spOtherInterface 这个只能接口指针调用QueryInterface()得到的IFun接口指针<br />　　  <br />　　  CComQIPtr &lt; IFun &gt; spFun ( pUnknown ); // 调用构造函数，由IUnknown的QueryInterface()得到IFun接口指针<br />　　  <br />　　  CComQIPtr &lt; IFun &gt; spFun = pOtherInterface; // = 运算符重载，含义和上面一样<br />　　  spFun = spOtherInterface; // 同上<br />　　  spFun = pUnknown; // 同上<br />　　  <br />　　  pUnknown-&gt;QueryInterface( IID_IFun, &amp;sp ); // 也可以通过QueryInterface赋值<br />　　  <br />　　  // 智能指针赋值后，可以用条件语句判断是否合法有效<br />　　  if ( spFun ){}  // 如果指针有效<br />　　  if ( NULL != spFun ){} // 如果指针有效<br />　　  <br />　　  if ( !spFun ){}  // 如果指针无效<br />　　  if ( NULL == spFun ){} // 如果指针无效 </font>
		</p>
		<p>
				<font face="Courier New" size="2">
				</font> </p>
		<p>
				<font face="Courier New" size="2">智能指针调用函数的方法： <br />　　  spFun.CoCreateInstance(...); // 等价与 API 函数::CoCreateInstance(...)<br />　　  spFun.QueryInterface(...); // 等价与 API 函数::QueryInterface()<br />　　  <br />　　  spFun-&gt;Add(...); // 调用内部接口指针的接口函数 </font>
		</p>
		<p>
				<font face="Courier New" size="2">　　  // 调用内部接口指针的QueryInterface()函数，其实效果和 spFun.QueryInterface(...) 一样<br />　　  spFun-&gt;QueryInterface(...); <br />　　  <br />　　  spFun.Release(); // 释放内部的接口指针，同时内部指针赋值为 NULL<br />　　  spFun-&gt;Release(); // 错！！！一定不要这么使用。<br />　　  // 因为这个调用并不把内部指针清空，那么析构的时候会被再次释放（释放了两次）<br /></font>
		</p>
<img src ="http://www.cppblog.com/alantop/aggbug/7051.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alantop/" target="_blank">AlanTop</a> 2006-05-13 03:44 <a href="http://www.cppblog.com/alantop/archive/2006/05/13/7051.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CComPtr和CComQIPtr的区别 </title><link>http://www.cppblog.com/alantop/archive/2006/05/13/7050.html</link><dc:creator>AlanTop</dc:creator><author>AlanTop</author><pubDate>Fri, 12 May 2006 19:36:00 GMT</pubDate><guid>http://www.cppblog.com/alantop/archive/2006/05/13/7050.html</guid><wfw:comment>http://www.cppblog.com/alantop/comments/7050.html</wfw:comment><comments>http://www.cppblog.com/alantop/archive/2006/05/13/7050.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/alantop/comments/commentRss/7050.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alantop/services/trackbacks/7050.html</trackback:ping><description><![CDATA[
		<div class="postTitle">CComPtr&lt;IWebBrowser2&gt; m_spWebBrowser2;<br />IUnknown *pUnknown;<br />pUnknown-&gt;QueryInterface(&amp;m_spWebBrowser2);<br /><br />CComQIPtr&lt;IWebBrowser2, &amp;IID_IWebBrowser2&gt; m_spWebBrowser2;<br />IUnknown *pUnknown;<br />m_spWebBrowser2 = pUnknown;<br /></div>
<img src ="http://www.cppblog.com/alantop/aggbug/7050.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alantop/" target="_blank">AlanTop</a> 2006-05-13 03:36 <a href="http://www.cppblog.com/alantop/archive/2006/05/13/7050.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>通过QueryInterface接口查询和使用IDispatch 接口进行操作的对比。</title><link>http://www.cppblog.com/alantop/archive/2006/05/13/7049.html</link><dc:creator>AlanTop</dc:creator><author>AlanTop</author><pubDate>Fri, 12 May 2006 19:29:00 GMT</pubDate><guid>http://www.cppblog.com/alantop/archive/2006/05/13/7049.html</guid><wfw:comment>http://www.cppblog.com/alantop/comments/7049.html</wfw:comment><comments>http://www.cppblog.com/alantop/archive/2006/05/13/7049.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/alantop/comments/commentRss/7049.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alantop/services/trackbacks/7049.html</trackback:ping><description><![CDATA[写一个提交网页表单的程序。比较了一下QueryInterface接口查询和使用IDispatch 接口进行操作<br />。<br />通过 QueryInterface 接口查询，然后再进行条件判断显然是比较烦琐的,但是效率比较高。适合特定的已知网页设计内容的程序。<br />例如自动进入126邮箱的程序。<br /><br />直接使用 IDispatch 接口进行操作的，这个方式执行起来稍微慢一些，但程序比较简单。<br /><br />找一个这个资料IShellWindows。<img src ="http://www.cppblog.com/alantop/aggbug/7049.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alantop/" target="_blank">AlanTop</a> 2006-05-13 03:29 <a href="http://www.cppblog.com/alantop/archive/2006/05/13/7049.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>二进制层次上使用组件的方法：</title><link>http://www.cppblog.com/alantop/archive/2006/04/29/6467.html</link><dc:creator>AlanTop</dc:creator><author>AlanTop</author><pubDate>Sat, 29 Apr 2006 11:08:00 GMT</pubDate><guid>http://www.cppblog.com/alantop/archive/2006/04/29/6467.html</guid><wfw:comment>http://www.cppblog.com/alantop/comments/6467.html</wfw:comment><comments>http://www.cppblog.com/alantop/archive/2006/04/29/6467.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/alantop/comments/commentRss/6467.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alantop/services/trackbacks/6467.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
				</span> </p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包容</span>
				<span lang="EN-US">(containment)</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：一个组件包含其他组件的接口指针。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">聚合</span>
				<span lang="EN-US">(aggregation)</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：外部组件直接传递内部组件的接口指针给客户的组件的复用机制</span>
				<span lang="EN-US">.</span>
		</p>
<img src ="http://www.cppblog.com/alantop/aggbug/6467.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alantop/" target="_blank">AlanTop</a> 2006-04-29 19:08 <a href="http://www.cppblog.com/alantop/archive/2006/04/29/6467.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>