﻿<?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++博客-C++ Programmer's Cookbook-随笔分类-Manage c++ /CLI</title><link>http://www.cppblog.com/mzty/category/695.html</link><description>&lt;br/&gt;  
&lt;br/&gt;
&lt;a href = "http://www.cppblog.com/mzty/archive/2007/03/02/19109.html"&gt;&lt;font size = 5 color ="#00FFFF"&gt;{C++ 基础}&lt;font/&gt;&lt;/a&gt;

&lt;a href = "http://www.cppblog.com/mzty/archive/2007/08/13/29922.html"&gt;&lt;font size = 5 color ="#00FFFF"&gt;{C++ 高级}&lt;font/&gt;&lt;/a&gt;

&lt;a href = "http://www.cppblog.com/mzty/archive/2008/07/18/56532.html"&gt;&lt;font size = 5 color ="#00FFFF"&gt;{C++/CLI}&lt;font/&gt;&lt;/a&gt;

&lt;a href = "http://www.cppblog.com/mzty/archive/2008/07/18/56533.html"&gt;&lt;font size = 5 color ="#00FFFF"&gt;{VC Team中文}&lt;font/&gt;&lt;/a&gt;

&lt;a href = "http://www.cppblog.com/mzty/archive/2007/04/16/22064.html"&gt;&lt;font size = 5 color ="#00FFFF"&gt;{C#界面，C++核心算法}&lt;font/&gt;&lt;/a&gt;

&lt;a href = "http://www.cppblog.com/mzty/archive/2007/03/04/19163.html"&gt;&lt;font size = 5 color ="#00FFFF"&gt;{设计模式}&lt;font/&gt;&lt;/a&gt;

&lt;a href = "
http://www.cppblog.com/mzty/archive/2007/03/04/19167.html"&gt;&lt;font size = 5 color ="#FF0000"&gt;{C#基础}&lt;font/&gt;&lt;/a&gt;





</description><language>zh-cn</language><lastBuildDate>Sat, 19 Jul 2008 00:57:57 GMT</lastBuildDate><pubDate>Sat, 19 Jul 2008 00:57:57 GMT</pubDate><ttl>60</ttl><item><title>超越 C++ 下一代 C++ — C++/CLI简介（转载）</title><link>http://www.cppblog.com/mzty/archive/2008/07/18/56536.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Fri, 18 Jul 2008 14:28:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2008/07/18/56536.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/56536.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2008/07/18/56536.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/56536.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/56536.html</trackback:ping><description><![CDATA[<span class=a14c id=zoom>&nbsp;<br>
<p><strong>一、绪论</strong>
<p>当微软推出VS.NET7实现了可扩展的托管C++后，C++程序员们反映不一。尽管大部分的程序员对于能够继续使用C++感到很欣慰，但几乎所有的人对于托管C++提供的晦涩语法感到很痛苦。微软明显从反馈中感觉到托管C++不是那么成功。
<p>2003年10月6日，ECMA（欧洲计算机制造商协会）宣布成立专家组，负责结合ISO标准C++与通用语言，开发一个可扩展语言的标准，这个新的可扩展语言被称为C++/CLI标准。这个标准将被VS.NET2005的C++编译器支持。
<p><strong>二、老语法存在的问题</strong>
<p>1、晦涩繁琐的语法和文法--这两个"双重底线"问题加重了阅读的负担。
<p>2、二流的CLI支持--相对与C#与VB.NET，MC++使用不方便的工作区来提供CLI支持，例如，它没有一个一一对应的结构来列举.NET的集合。
<p>3、C++与.NET粗陋地结合--对于CLI类型，你不能使用C++的特色，例如模板；同样，对于C++类型，你不能使用CLI的特色，例如碎片帐集。
<p>4、令人混淆的指针--非托管的C++的指针及托管的引用指针都使用*语法，这非常令人混淆，因为-gc指针与托管指针在本质和行为上完全不同。
<p>5、MFC编译器不能产生可校验的代码。
<p><strong>三、C++/CLI给我们提供了什么？</strong>
<p>1、优雅流畅的语法和文法--C++/CLI为C++开发人员书写托管代码提供了一种非常自然的感觉，并且它提供了非托管代码到托管代码的平滑过度。以前所谓的"双重底线"问题现在已经荡然无存。
<p>2、一流的CLI支持--CLI特色，例如属性、碎片集合和属类得到了直接支持，此外，C++/CLI还准许将这些特色用于本地非托管的类。
<p>3、一流的C++类支持--C++特色，例如模板和析构函数对于拖管和非拖管类继续有效。实际上，C++/CLI是你可以"表面上"在栈或C++本地堆上声明一个.NET类型唯一的.NET语言。
<p>4、在.NET与C++之间的沟壑上架起了一座桥梁--C++开发人员在抨击BCL时不再象离开水的鱼。
<p>5、C++/CLI编译器产生的可执行文件完全是可校验的。
<p><strong>四、"Hello World"小程序</strong>
<p><ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
    <tbody>
        <tr>
            <td class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6>
            <pre><ccid_code>using namespace System;
            void _tmain()
            {
            Console::WriteLine("Hello World");
            }</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr>
<p>上述代码除了不需要引用mscorlib.dll库外，与老的语法没有太大的区别，因为无论你什么时候使用/clr进行编辑，编译器都可以暗中进行引用（现在默认的是/clr:newSyntax）。
<p><strong>五、句柄</strong>
<p>与老的语法主要的混淆是我们习惯于使用*符号来声明拖管引用或非拖管指针，在C++/CLI里微软引入了句柄的概念。
<p><ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
    <tbody>
        <tr>
            <td class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6>
            <pre><ccid_code>void _tmain()
            {
            //The ^ punctuator represents a handle
            String^ str = "Hello World";
            Console::WriteLine(str);
            }</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr>
<p>^符号代表一个托管对象（声明时看上去象个帽子），按照CLI的规定，句柄代表一个拖管对象的引用。句柄在CLI中是新的语法，相当于C++中的-gc指针。句柄与指针不再混淆，在本质上两者完全不同。
<p><strong>六、句柄与指针是怎样区分开来的？</strong>
<p>1、指针声明时使用*符号，而句柄使用^符号。
<p>2、句柄是针对拖管堆上对象的拖管引用，而指针仅仅指向内存中的一个地址。
<p>3、指针很稳定，GC循环不会影响到它；句柄在基于GC或内存紧张的情况下，可以指向不同的内存位置。
<p>4、对于指针，程序开发人员必须"显式"地删除，否则会面临泄露的危险，而对于句柄，是否进行显式删除则完全根据程序人员的爱好了。
<p>5、句柄一定要指向一个具体的类型，即所谓的类型安全性，而指针明显不是这样，你决不可以将一个句柄指向Void^类型。
<p>6、正如new操作符返回一个指针一样，gcnew返回一个句柄。
<p><strong>七、CLR对象示例</strong>
<p><ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
    <tbody>
        <tr>
            <td class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6>
            <pre><ccid_code>void _tmain()
            {
            String^ str = gcnew String("Hello World");
            Object^ o1 = gcnew Object();
            Console::WriteLine(str);
            }</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr>
<p>关键字gcnew用来实例化一个CLI对象，而且它返回一个指向在CLR堆上的对象的句柄，gcnew的优点在于它可以方便的让我们区分拖管和非拖管的实例对象。
<p>大部分情况下，gcnew关键字和^操作符提供了你用来进行BCL的一切手段，但是很明显你需要创建和声明属于自己的拖管类和接口。
<p><strong>八、声明类型 </strong>
<p>CLR类型有一个形容词前缀用来说明类型的种类，下面是C++/CLI中的类型声明示例：
<p><ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
    <tbody>
        <tr>
            <td class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6>
            <pre><ccid_code>1、 CLR types
            o Reference types
            &#167; ref class RefClass;
            &#167; ref struct RefClass;
            2、 Value types
            &#167; value class ValClass;
            &#167; value struct ValClass;
            o Interfaces
            &#167; interface class IType;
            &#167; interface struct IType;
            o Enumerations
            &#167; enum class Color;
            &#167; enum struct Color;
            3、 Native types
            o class Native;
            o struct Native;
            示例：
            using namespace System;
            interface class IDog
            {
            void Bark();
            };
            ref class Dog : IDog
            {
            public:
            void Bark()
            {
            Console::WriteLine("Bow wow wow");
            }
            };
            void _tmain()
            {
            Dog^ d = gcnew Dog();
            d-&gt;Bark();
            }</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr>
<p>上述程序中的代码与老的C++语言相比看上去非常简洁，在以往的C++代码中，至少要用到-gc和-interface这两个关键词。
<p><strong>九、装箱/拆箱操作</strong>
<p>在C++/CLI中，加箱是隐含的，而且类型是安全的，一个二进制的拷贝被执行并在CLR堆上形成一个对象，去箱是显式的，仅仅需要使用reinterpret_cast操作符来解除引用。
<p><ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
    <tbody>
        <tr>
            <td class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6>
            <pre><ccid_code>void _tmain()
            {
            int z = 44;
            Object^ o = z; //implicit boxing
            int y = *reinterpret_cast&lt;int^&gt;(o); //unboxing
            Console::WriteLine("  ",o,z,y);
            z = 66;
            Console::WriteLine("  ",o,z,y);
            }
            // 输出结果如下：
            // 44 44 44
            // 44 66 44</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr>
<p>在上述代码中，"o"对象是一个加箱的拷贝，从第二个语句Console::WriteLine.的输出可以很明显地看到，它并没有涉及到int类型的整数值。
<p>当你对一种数值类型进行加箱操作时，返回的对象记住了最初的数值类型。
<p><ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
    <tbody>
        <tr>
            <td class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6>
            <pre><ccid_code>void _tmain()
            {
            int z = 44;
            float f = 33.567;
            Object^ o1 = z;
            Object^ o2 = f;
            Console::WriteLine(o1-&gt;GetType());
            Console::WriteLine(o2-&gt;GetType());
            }
            // Output
            // System.Int32
            // System.Single</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr>
<p>因此不能对不同类型的对象进行去箱操作。
<p><ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
    <tbody>
        <tr>
            <td class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6>
            <pre><ccid_code>void _tmain()
            {
            int z = 44;
            float f = 33.567;
            Object^ o1 = z;
            Object^ o2 = f;
            int y = *reinterpret_cast&lt;int^&gt;(o2);//System.InvalidCastException
            float g = *reinterpret_cast&lt;float^&gt;(o1);//System.InvalidCastException
            }</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr>
<p>如果你非尝试这么做，那么你将得到一个System.InvalidCastException。让我们来探讨一下完美的类型安全性，如果你要看内部代码，你将看到微软的内部箱在实际中的运用。例如：
<p><ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
    <tbody>
        <tr>
            <td class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6>
            <pre><ccid_code>void Box2()
            {
            float y=45;
            Object^ o1 = y;
            }</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr>
<p>编译后的代码是：
<p><ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
    <tbody>
        <tr>
            <td class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6>
            <pre><ccid_code>.maxstack 1
            .locals (float32 V_0, object V_1)
            ldnull
            stloc.1
            ldc.r4 45.
            stloc.0
            ldloc.0
            box [mscorlib]System.Single
            stloc.1
            ret</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr>
<p>根据微软的内部文档，箱操作将未加工的类型转换为一个具体类型的实例，这项工作的完成通过创建一个新的对象并将数据拷贝到这个新分配的对象。
<p><strong>十、写在后面的话</strong>
<p>为什么很多人已经可以使用C、C++、.NET来开发程序但还在积极学习C++/CLI呢，我想有四个方面的原因：
<p>1、从编译器直到内层都还在支持C++代码；
<p>2、C++/CLI对于其他标准来说无意是具有毁灭性地；
<p>3、与生俱来的内部支持胜过所有其他CLI语言
<p>4、所有在MFC中出现的下划线都已不再存在。</p>
</span><img src ="http://www.cppblog.com/mzty/aggbug/56536.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2008-07-18 22:28 <a href="http://www.cppblog.com/mzty/archive/2008/07/18/56536.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++/CLI 中文</title><link>http://www.cppblog.com/mzty/archive/2008/07/18/56532.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Fri, 18 Jul 2008 14:18:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2008/07/18/56532.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/56532.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2008/07/18/56532.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/56532.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/56532.html</trackback:ping><description><![CDATA[<br>C++/CLI中文文章：<br><br><br>一，<br><br><a id=_378b1b4664b5_HomePageDays_DaysList_ctl00_DayItem_DayList_ctl01_TitleUrl href="http://www.cppblog.com/mzty/archive/2008/07/18/56531.html"><font color=#000000>C++/CLI：第一流的CLI语言(转载)</font></a> <br><br>二，<img src ="http://www.cppblog.com/mzty/aggbug/56532.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2008-07-18 22:18 <a href="http://www.cppblog.com/mzty/archive/2008/07/18/56532.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++/CLI：第一流的CLI语言(转载)</title><link>http://www.cppblog.com/mzty/archive/2008/07/18/56531.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Fri, 18 Jul 2008 14:12:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2008/07/18/56531.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/56531.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2008/07/18/56531.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/56531.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/56531.html</trackback:ping><description><![CDATA[<h1 id=artibodyTitle>&nbsp;</h1>
<h1>C++/CLI：第一流的CLI语言 <br>2005-08-25 11:25 作者： 朱先忠编译 出处： 天极网 责任编辑：方舟 </h1>
<p><strong>1. 简介<br><br></strong>　　本文并不是为了奉承C++/CLI的辉煌，也不是为了贬低其它如C#或者VB.NET等语言，相反，这只是一个非官方的、以一个喜欢这种语言的非<a class=bluekey href="http://com.chinabyte.com/microsoft/" target=_blank><u><font color=#0000ff>微软</font></u></a>雇员身份来论证C++/CLI有它的自己的唯一的角色，可作为第一流的.NET编程语言。<br><br>　　一个不断在新闻组和技术论坛上出现的问题是，当象C#和VB.NET这样的语言更适合于这种用途时，为什么要使用C++来开发.NET应用<a class=bluekey href="http://product.yesky.com/software/" target=_blank><u><font color=#0000ff>软件</font></u></a>。通常这样一些问题后面的评论说是，C++语法是怎样的复杂和令人费解，C++现在是怎样一种过时的语言，还有什么VS.NET<a class=bluekey href="http://design.yesky.com/" target=_blank><u><font color=#0000ff>设计</font></u></a>者已不再像支持C#和VB.NET一样继续支持C++。其中一些猜疑是完全荒谬的，但有些说法部分正确。希望本文有助于澄清所有这些围绕C++/CLI语言及其在VS.NET语言层次中的地位的疑惑，神秘和不信任。请记住，本作者既不为微软工作也没有从微软那里取得报酬，只是想从技术上对C++/CLI作一评判。<br><br>　　<strong>2. 快速简洁的本机interop</strong><br><br>　　除了P/Invoke机制可用在另外的象C#或VB.NET这样的语言外，C++提供了一种独有的interop机制，称作C++ interop。C++ interop比P/Invoke直观得多，因为你只是简单地#include需要的头文件，并与需要的库进行链接就能象在本机C++中一样调用任何函数。另外，它比P/Invoke速度快--这是很容易能证明的。现在，可争辩的是在实际应用软件的开发中，经由C++ interop获得的性能好处与花在用户接口交互、数据库存取、<a class=bluekey href="http://product.yesky.com/net/" target=_blank><u><font color=#0000ff>网络</font></u></a>数据转储、复杂数学算法等方面的时间相比可以被忽略，但是事实是在有些情况下，甚至通过每次interop调用节省的几个纳秒也能给全局应用<a class=bluekey href="http://dev.yesky.com/" target=_blank><u><font color=#0000ff>程序</font></u></a>性能/响应造成巨大影响，这是绝对不能被忽视的。下面有两部分代码片断(一个是使用P/Invoke机制的C#程序，一个是使用C++ Interop机制的C++程序)，我分别记录了其各自代码重复执行消耗的时间(毫秒)。不管你如何解释这些数据，不管这会对你的应用程序产生什么影响，全是你的事。我仅打算事实性地指出，C++代码的执行速度要比C#(其中使用了较多的本机interop调用)快。<br><br>　　1) C#程序(使用P/Invoke)<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>[SuppressUnmanagedCodeSecurity] <br>[DllImport("kernel32.dll")]<br>static extern uint GetTickCount();<br>[SuppressUnmanagedCodeSecurity] <br>[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]<br>static extern uint GetWindowsDirectory(<br>[Out] StringBuilder lpBuffer, uint uSize);<br>static void Test(int x)<br>{<br>StringBuilder sb = new StringBuilder(512);<br>for (int i = 0; i &lt; x; i++)<br>GetWindowsDirectory(sb, 511);<br>}<br>static void DoTest(int x)<br>{<br>uint init = GetTickCount();<br>Test(x);<br>uint tot = GetTickCount() - init;<br>Console.WriteLine("Took {0} milli-seconds for {1} iterations",tot, x);<br>}<br>static void Main(string[] args)<br>{<br>DoTest(50000);DoTest(500000);DoTest(1000000);DoTest(5000000);<br>Console.ReadKey(true);<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　2) C++程序(使用C++ Interop)<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>void Test(int x)<br>{<br>TCHAR buff[512];<br>for(int i=0; i&lt;x; i++)<br>GetWindowsDirectory(buff, 511);<br>}<br>void DoTest(int x)<br>{<br>DWORD init = GetTickCount();<br>Test(x);<br>DWORD tot = GetTickCount() - init;<br>Console::WriteLine("Took {0} milli-seconds for {1} iterations",tot, x);<br>}<br>int main(array&lt;System::String ^&gt; ^args)<br>{ <br>DoTest(50000);DoTest(500000);DoTest(1000000);DoTest(5000000);<br>Console::ReadKey(true);<br>return 0;<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　3) 速度比较<br><br>
<table cellSpacing=0 cellPadding=2 width="90%" align=center border=1>
    <tbody>
        <tr>
            <td>重复次数 </td>
            <td>C# 程序</td>
            <td>C++程序</td>
        </tr>
        <tr>
            <td>50,000</td>
            <td>61 </td>
            <td>10</td>
        </tr>
        <tr>
            <td>500,000</td>
            <td>600 </td>
            <td>70</td>
        </tr>
        <tr>
            <td>1,000,000</td>
            <td>1162</td>
            <td>140</td>
        </tr>
        <tr>
            <td>5,000,000</td>
            <td>6369</td>
            <td>721</td>
        </tr>
    </tbody>
</table>
　　 <br>　　其性能差别真是令人惊愕！这的确是说明为什么要使用C++/CLI的一个好理由，如果你在使用本机interop进行开发，那么性能！完全由于性能，我就将被迫借助本机interop来实现并非基于web的.NET应用程序。当然，为什么我想要使用.NET来开发需要大量本机interop技术的应用程序完全是另外一个问题。<br><br>　　如果你仍怀疑这种性能优势，有另外的理由来说明你为什么不得不使用C++/CLI而不是C#或VB.NET——源码膨胀！下面是一个C++函数的例子，它使用了IP帮助者API来枚举一台机器上的网络适配器并且列出与每个适配器相联系的所有IP地址。<br><br>　　4) 枚举n/w适配器的C++代码<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>void ShowAdapInfo()<br>{<br>PIP_ADAPTER_INFO pAdapterInfo = NULL;<br>ULONG OutBufLen = 0;<br>//得到需要的缓冲区大小<br>if(GetAdaptersInfo(NULL,&amp;OutBufLen)==ERROR_BUFFER_OVERFLOW)<br>{<br>int divisor = sizeof IP_ADAPTER_INFO;<br>#if _MSC_VER &gt;= 1400<br>if( sizeof time_t == 8 ) divisor -= 8;<br>#endif<br>pAdapterInfo = new IP_ADAPTER_INFO[OutBufLen/divisor];<br>//取得适配器信息<br>if( GetAdaptersInfo(pAdapterInfo, &amp;OutBufLen) != ERROR_SUCCESS )<br>{//调用失败 }<br>else <br>{<br>int index = 0;<br>while(pAdapterInfo)<br>{<br>Console::WriteLine(gcnew String(pAdapterInfo-&gt;Description));<br>Console::WriteLine("IP Address list : ");<br>PIP_ADDR_STRING pIpStr = &amp;pAdapterInfo-&gt;IpAddressList;<br>while(pIpStr)<br>{<br>Console::WriteLine(gcnew tring(pIpStr-&gt;IpAddress.String));<br>pIpStr = pIpStr-&gt;Next;<br>}<br>pAdapterInfo = pAdapterInfo-&gt;Next;<br>Console::WriteLine();<br>}<br>}<br>delete[] pAdapterInfo;<br>}<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　现在让我们看一个使用P/Invoke的C#版本。<br><br>　　5) 使用P/Invoke技术的C#版本<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>const int MAX_ADAPTER_NAME_LENGTH = 256;<br>const int MAX_ADAPTER_DESCRIPTION_LENGTH = 128;<br>const int MAX_ADAPTER_ADDRESS_LENGTH = 8;<br>const int ERROR_BUFFER_OVERFLOW = 111;<br>const int ERROR_SUCCESS = 0;<br>[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]<br>public struct IP_ADDRESS_STRING<br>{<br>[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]<br>public string Address;<br>}<br>[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]<br>public struct IP_ADDR_STRING<br>{<br>public IntPtr Next;<br>public IP_ADDRESS_STRING IpAddress;<br>public IP_ADDRESS_STRING Mask;<br>public Int32 Context;<br>}<br>[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]<br>public struct IP_ADAPTER_INFO<br>{<br>public IntPtr Next;<br>public Int32 ComboIndex;<br>[MarshalAs(UnmanagedType.ByValTStr, <br>SizeConst = MAX_ADAPTER_NAME_LENGTH + 4)]<br>public string AdapterName;<br>[MarshalAs(UnmanagedType.ByValTStr, <br>SizeConst = MAX_ADAPTER_DESCRIPTION_LENGTH + 4)]<br>public string AdapterDescription;<br>public UInt32 AddressLength;<br>[MarshalAs(UnmanagedType.ByValArray, <br>SizeConst = MAX_ADAPTER_ADDRESS_LENGTH)]<br>public byte[] Address;<br>public Int32 Index;<br>public UInt32 Type;<br>public UInt32 DhcpEnabled;<br>public IntPtr CurrentIpAddress;<br>public IP_ADDR_STRING IpAddressList;<br>public IP_ADDR_STRING GatewayList;<br>public IP_ADDR_STRING DhcpServer;<br>public bool HaveWins;<br>public IP_ADDR_STRING PrimaryWinsServer;<br>public IP_ADDR_STRING SecondaryWinsServer;<br>public Int32 LeaseObtained;<br>public Int32 LeaseExpires;<br>}<br>[DllImport("iphlpapi.dll", CharSet = CharSet.Ansi)]<br>public static extern int GetAdaptersInfo(IntPtr pAdapterInfo, ref int pBufOutLen);<br>static void ShowAdapInfo()<br>{<br>int OutBufLen = 0; <br>//得到需要的缓冲区大小<br>if( GetAdaptersInfo(IntPtr.Zero, ref OutBufLen) == <br>ERROR_BUFFER_OVERFLOW )<br>{<br>IntPtr pAdapterInfo = Marshal.AllocHGlobal(OutBufLen); <br>//取得适配器信息<br>if( GetAdaptersInfo(pAdapterInfo, ref OutBufLen) != ERROR_SUCCESS )<br>{ //调用失败了 }<br>else{<br>while(pAdapterInfo != IntPtr.Zero)<br>{<br>IP_ADAPTER_INFO adapinfo = <br>(IP_ADAPTER_INFO)Marshal.PtrToStructure(<br>pAdapterInfo, typeof(IP_ADAPTER_INFO));<br>Console.WriteLine(adapinfo.AdapterDescription);<br>Console.WriteLine("IP Address list : ");<br>IP_ADDR_STRING pIpStr = adapinfo.IpAddressList;<br>while (true){<br>Console.WriteLine(pIpStr.IpAddress.Address);<br>IntPtr pNext = pIpStr.Next;<br>if (pNext == IntPtr.Zero)<br>break;<br>pIpStr = (IP_ADDR_STRING)Marshal.PtrToStructure(<br>pNext, typeof(IP_ADDR_STRING));<br>}<br>pAdapterInfo = adapinfo.Next;<br>Console.WriteLine(); <br>}<br>}<br>Marshal.FreeHGlobal(pAdapterInfo);<br>}<br>}</td>
        </tr>
    </tbody>
</table>
<br><br>3. 栈语义和确定性的析构<br><br>　　C++经由栈语义模仿给了我们确定性的析构。简言之，栈语义是Dispose模式的良好的语法替代品。但是它在语义上比C# using块语法更直观些。请看下列的C#和C++代码段（都做一样的事情-连接两个文件的内容并把它写到第三个文件中）。<br><br>　　1) C#代码--使用块语义<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>public static void ConcatFilestoFile(String file1, String file2, String outfile)<br>{<br>String str;<br>try{<br>using (StreamReader tr1 = new StreamReader(file1))<br>{<br>using (StreamReader tr2 = new StreamReader(file2))<br>{<br>using (StreamWriter sw = new StreamWriter(outfile))<br>{<br>while ((str = tr1.ReadLine()) != null)<br>sw.WriteLine(str);<br>while ((str = tr2.ReadLine()) != null)<br>sw.WriteLine(str);<br>}<br>}<br>}<br>}<br>catch (Exception e)<br>{ Console.WriteLine(e.Message); }<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　2) C++代码--栈语义<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>static void ConcatFilestoFile(String^ file1, String^ file2, String^ outfile)<br>{<br>String^ str;<br>try{<br>StreamReader tr1(file1);<br>StreamReader tr2(file2);<br>StreamWriter sw(outfile);<br>while(str = tr1.ReadLine())<br>sw.WriteLine(str);<br>while(str = tr2.ReadLine())<br>sw.WriteLine(str);<br>}<br>catch(Exception^ e)<br>{ Console::WriteLine(e-&gt;Message); }<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　C#代码与相等的C++ 代码相比不仅免不了冗长，而且using块语法让程序员自己明确地指定他想在哪儿调用Dispose（using块的结束处），而使用C++/CLI的栈语义，只需让编译器使用常规的范围规则来处理它即可。事实上，这使得在C#中修改代码比在C++中更乏味-作为一实例，让我们修改这些代码以便即使仅存在一个输入文件也能创建输出文件。请看下面修改后的C#和C++代码。<br><br>　　3) 修改后的C#代码<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>public static void ConcatFilestoFile(String file1, String file2, String outfile)<br>{<br>String str;<br>try{<br>using (StreamWriter sw = new StreamWriter(outfile))<br>{<br>try{<br>using (StreamReader tr1 = new StreamReader(file1))<br>{<br>while ((str = tr1.ReadLine()) != null)<br>sw.WriteLine(str);<br>}<br>}<br>catch (Exception) { }<br>using (StreamReader tr2 = new StreamReader(file2))<br>{<br>while ((str = tr2.ReadLine()) != null)<br>sw.WriteLine(str);<br>}<br>}<br>}<br>catch (Exception e){ }<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　把针对StreamWriter的using块放到顶层需要重新调整using块结构--这在上面情况下显然不是个大问题，但是对于实际开发中的修改，这可能是相当模糊的且易导致逻辑错误的。<br><br>　　4) 修改后的C++代码<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>static void ConcatFilestoFile(String^ file1, String^ file2, String^ outfile)<br>{<br>String^ str;<br>try{<br>StreamWriter sw(outfile);<br>try{<br>StreamReader tr1(file1); <br>while(str = tr1.ReadLine())<br>sw.WriteLine(str); <br>}<br>catch(Exception^){} <br>StreamReader tr2(file2); <br>while(str = tr2.ReadLine())<br>sw.WriteLine(str); <br>}<br>catch(Exception^){}<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　这样不是比在C#中的做更容易些吗？我恰好把StreamWriter声明移到了顶部并增加了一个额外的try块，就这些。甚至对于象在我的示例代码片断中的琐碎事情，如果所涉及的复杂性在C++中大大减少，那么，当你工作于更大的工程时你能想象使用栈语义对你的编码效率千万的影响。<br><br>　　还不确信？好，让我们看一下成员对象和它们的析构吧。Imagine CLI GC类R1和R2，二者都实现了Idisposable接口且都有函数F()，还有一个CLI GC类R，它有R1和R2成员和一个函数F()-它内部地调用R1和R2上的F()成员函数。让我们先看C#实现。<br><br>　　5) 一个disposable类继承层次的C#实现<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>class R1 : IDisposable{<br>public void Dispose() { }<br>public void F() { }<br>}<br>class R2 : IDisposable{<br>public void Dispose() { }<br>public void F() { }<br>}<br>class R : IDisposable{<br>R1 m_r1 = new R1();<br>R2 m_r2 = new R2();<br>public void Dispose() <br>{ <br>m_r1.Dispose();<br>m_r2.Dispose();<br>}<br>public void F() <br>{<br>m_r1.F();<br>m_r2.F();<br>}<br>public static void CallR()<br>{<br>using(R r = new R())<br>{r.F();}<br>}<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　这里有几件事情要做：必须为每个disposable 类手工实现IDisposable接口，对于具有成员R1和R2的类R，Dispose方法也需要调用成员类上的Dispose。现在让我们分析上面几个类的C++实现。<br><br>　　6) 等价的C++实现<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>ref class R1<br>{<br>public:<br>~R1(){}<br>void F(){}<br>};<br>ref class R2<br>{<br>public:<br>~R2(){}<br>void F(){}<br>};<br>ref class R<br>{<br>R1 m_r1;<br>R2 m_r2;<br>public:<br>~R(){}<br>void F()<br>{<br>m_r1.F();<br>m_r2.F();<br>}<br>static void CallR()<br>{<br>R r;<br>r.F();<br>}<br>};</td>
        </tr>
    </tbody>
</table>
<br>　　注意，这里不再有手工的Idisposable接口实现(我们的类中仅建立了析构器)而且最好的部分--类R的析构器(Dispose方法)并没有在该类可能含有的可释放的成员上调用Dispose-它没有必要这样做，编译器自动为之生成所有的代码！ <br><br>4. 混合类型<br><br>　　我们知道，C++支持本机类型-总是如此；C++支持CLI类型-本文正是特别强调这一点；它还支持混合类型-具有CLI成员的本机类型和具有本机成员的CLI类型！请尽管考虑所有你能的可能需求。<br><br>　　注意，谈到Whidbey，混合类型实现还不完整；就我从Brandon，Herb和Ronald发表的材料的理解得知，存在这种相当酷的类型--统一模型，它将在Orcas中实现--你能够在本机C++堆上new/delete CLI类型，而且也能够在CLI堆上gcnew/delete本机类型。但既然这是Whidbey以后的东西，本文不讨论统一模型。<br><br>　　在我谈论你何时使用混合类型以前，我想向你说明什么是混合类型。如果你理解混合类型，请跳过下面几段。这里引用Brandon Bray的说法："一种混合类型，或者是本机类ref类（需要有对象成员），或者是通过声明或继承被分配在垃圾回收堆或本机堆上的。"因此如果你有一个托管类型或者有一个有托管成员的本机类型，你就有了一个混合类型。VC++ Whidbey不直接支持混合类型(统一类型模型是一种Whidbey之后的概念)，但是它给我们划定了实现混合类型的条件。让我们开始讨论包含托管成员的本机类型。<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>ref class R<br>{<br>public:<br>void F(){}<br>//假定 non-trivial ctor/dtor<br>R(){}<br>~R(){}<br>};</td>
        </tr>
    </tbody>
</table>
<br>　　在我的例子中，设想该托管类型R有一个non-trivial构造器和一个non-trivial析构器。<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>class Native<br>{<br>private:<br>gcroot&lt;R^&gt; m_ref; <br>public:<br>Native():<br>m_ref(gcnew R()){} <br>~Native()<br>{ delete m_ref; }<br>void DoF()<br>{ m_ref-&gt;F(); }<br>};</td>
        </tr>
    </tbody>
</table>
<br>　　既然，我不能在我的类中拥有一个R成员，我使用了gcroot模板类(在gcroot.h中声明，但是你要用"#include vcclr.h")，它包装了System::Runtime::InteropServices::GCHandle结构。它是个象类一样的灵敏指针，它重载了运算符-&gt;以返回用作模板参数的托管类型。因此在上面类中，我可以使用m_ref，就好象我已经声明它是R^，而且你能在DoF函数中看到这正在起作用。实际上你可以节省delete，这可以通过使用auto_gcroot(类似于std::auto_ptr，在msclr\auto_gcroot.h文件中声明)代替gcroot来实现。下面是一个更好些的使用auto_gcroot的实现。<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>class NativeEx<br>{<br>private:<br>msclr::auto_gcroot&lt;R^&gt; m_ref; <br>public:<br>NativeEx() : m_ref(gcnew R()){}<br>void DoF()<br>{ m_ref-&gt;F(); }<br>};</td>
        </tr>
    </tbody>
</table>
<br>　　下面让我们看相反的情形：一个CLI类的本机成员。<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>ref class Managed<br>{<br>private:<br>Native* m_nat;<br>public:<br>Managed():m_nat(new Native()){ }<br>~Managed()<br>{ delete m_nat; }<br>!Managed()<br>{ delete m_nat;<br>#ifdef _DEBUG<br>throw gcnew Exception("Oh, finalizer got called!");<br>#endif<br>}<br>void DoF()<br>{ m_nat-&gt;DoF(); }<br>};</td>
        </tr>
    </tbody>
</table>
<br>　　我不能定义一个Native对象来作为一个ref类成员，因此需要使用一个Native*对象来代替。我在构造器中new该Native对象，然后在析构器和finalizer中delete它。如果你运行该工程的调试版，在执行到finalizer时将抛出一个异常- 因此开发者可以马上添加一个对delete的调用或为他的CLI类型使用栈语义技术。奇怪的是，库开发小组没有建立一个gcroot的反向实现-但这不是个大问题，我们可以自己写。<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>template&lt;typename T&gt; ref class nativeroot<br>{<br>T* m_t;<br>public:<br>nativeroot():m_t(new T){}<br>nativeroot(T* t):m_t(t){}<br>T* operator-&gt;()<br>{ return m_t; }<br>protected:<br>~nativeroot()<br>{ delete m_t; }<br>!nativeroot()<br>{<br>delete m_t;<br>#ifdef _DEBUG<br>throw gcnew Exception("Uh oh, finalizer got called!");<br>#endif<br>}<br>};</td>
        </tr>
    </tbody>
</table>
<br>　　这仅是个相当简单的灵敏指针实现，就象一个负责本机对象分配/回收的ref类。不管怎样，借助nativeroot模板类，我们可以如下修改托管类：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>ref class ManagedEx<br>{<br>private:<br>nativeroot&lt;Native&gt; m_nat;<br>public:<br>void DoF()<br>{ m_nat-&gt;DoF(); }<br>};</td>
        </tr>
    </tbody>
</table>
<br>　　好，关于混合类型的最大问题是什么呢？你可能问。最大问题是，现在你能混合使用你的MFC、ATL、WTL、STL代码仓库和.NET框架，并用可能的最直接的方式-只需写你的混合模式代码并编译实现!你可以建立在一个DLL库中建立MFC 类，然后建立一个.NET应用程序来调用这个DLL，还需要把.NET类成员添加到你的MFC类（也实现可以相反的情况）。<br><br>　　作为一例，设想你有一MFC对话框--它通过一个多行的编辑框接受来自用户的数据-现在，你有一新的要求-显示一个只读编辑框，它将显示当前在该多行编辑框中文本的md5哈希结果。你的队友正在悲叹他们将必须花费几个小时钻研crypto API，而你的上司在担忧你们可能必须要买一个第三方加密库；那正是你在他们面前树立形象的时候，你宣布你将在15分钟内做完这项任务。下面是解决的办法：<br><br>　　添加一个新的编辑框到你的对话框资源中，并且添加相应的DDX变量。选择/clr编译模式并且添加下列代码到你的对话框的头文件中： <br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>#include &lt;msclr\auto_gcroot.h&gt;<br>using namespace System::Security::Cryptography;</td>
        </tr>
    </tbody>
</table>
<br>　　使用auto_gcroot模板来声明一个MD5CryptoServiceProvider成员：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>protected:<br>msclr::auto_gcroot&lt;MD5CryptoServiceProvider^&gt; md5;</td>
        </tr>
    </tbody>
</table>
<br>　　在OnInitDialog过程中，gcnew MD5CryptoServiceProvider成员。<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>md5 = gcnew MD5CryptoServiceProvider();</td>
        </tr>
    </tbody>
</table>
<br>　　并且为多行编辑框添加一个EN_CHANGE处理器：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>void CXxxxxxDlg::OnEnChangeEdit1()<br>{<br>using namespace System;<br>CString str;<br>m_mesgedit.GetWindowText(str);<br>array&lt;Byte&gt;^ data = gcnew array&lt;Byte&gt;(str.GetLength());<br>for(int i=0; i&lt;str.GetLength(); i++)<br>data[i] = static_cast&lt;Byte&gt;(str[i]);<br>array&lt;Byte&gt;^ hash = md5-&gt;ComputeHash(data);<br>CString strhash;<br>for each(Byte b in hash)<br>{<br>str.Format(_T("%2X "),b);<br>strhash += str;<br>}<br>m_md5edit.SetWindowText(strhash);<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　这里使用了混合类型：一个本机Cdialog派生类，该类含有一个MD5CryptoServiceProvider成员(CLI类型)。你可以轻易地试验相反的情况（如早期的代码片断已显示的）——可以建立一个Windows表单应用程序而且可能想利用一个本机类库--这不成问题，使用上面定义的模板nativeroot即可。<br><br>5. 托管模板<br><br>　　也许你对泛型的概念已很清楚了，它帮助你避免进入C++的模板梦魇，它是实现模板的最佳方式，等等。好，假设这些全部正确，C++/CLI支持泛型就象任何其它CLI语言一样-但是它有而其它一些CLI语言还没有的是它还支持托管模板-也就是模板化的ref和value类。如果你以前从未使用过模板，你不能一下欣赏这么多优点，但是如果你有模板使用背景而且你已发现了泛型中存在的可能限制你编码的方式，托管模板将会大大减轻你的负担。你能联合使用泛型和模板- 事实上有可能用一个托管类型的模板参数来实例化一个泛型类型(尽管相反的情形是不可能的，因为运行时刻实例化由泛型所用)。STL.NET (或STL/CLR)以后讨论，请很好地利用泛型和托管模板的混合编程吧。<br><br>　　泛型使用的子类型约束机制将防止你写出下面的代码：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>generic&lt;typename T&gt; T Add(T t1, T t2)<br>{ return t1 + t2; }</td>
        </tr>
    </tbody>
</table>
<br>　　编译错误：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>error C2676: binary &#8217;+&#8217; : &#8217;T&#8217; does not define this operator or a conversion to a type acceptable to the predefined operator</td>
        </tr>
    </tbody>
</table>
<br>　　现在请看相应的模板版本：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>template&lt;typename T&gt; T Add(T t1, T t2)<br>{ return t1 + t2; }</td>
        </tr>
    </tbody>
</table>
<br>　　那么就可以这样做：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>int x1 = 10, x2 = 20;<br>int xsum = Add&lt;int&gt;(x1, x2);</td>
        </tr>
    </tbody>
</table>
<br>　　还可以这样做：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>ref class R<br>{<br>int x; <br>public:<br>R(int n):x(n){}<br>R^ operator+(R^ r)<br>{ return gcnew R(x + r-&gt;x); }<br>};<br>//...<br>R^ r1 = gcnew R(10);<br>R^ r2 = gcnew R(20);<br>R^ rsum = Add&lt;R^&gt;(r1, r2);</td>
        </tr>
    </tbody>
</table>
<br>　　这在一个象int的本机类型以及一个ref类型(只要ref类型有一个+运算符)情况下都能工作良好。这个泛型缺点不是一个调试错误或缺陷-它是设计造成的。泛型的实例化是在运行时通过调用配件集实现的，因此编译器不能确知一特定操作能被施行于一个泛型参数，除非它匹配一个子类型约束，因此编译器在定义泛型时解决这个问题。当你使用泛型时的另外一个妨碍是，它不会允许你使用非类型参数。下列泛型类定义不会编译：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>generic&lt;typename T, int x&gt; ref class G{};</td>
        </tr>
    </tbody>
</table>
<br>　　编译错：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>error C2978: syntax error : expected &#8217;typename&#8217; or &#8217;class&#8217;; found type &#8217;int&#8217;; non-type parameters are not supported in generics</td>
        </tr>
    </tbody>
</table>
<br>　　与托管模板相比较：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>template&lt;typename T, int x = 0&gt; ref class R{};</td>
        </tr>
    </tbody>
</table>
<br>　　如果你开始感激C++向你提供了泛型和托管模板，那么请看下面这一个例子： <br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>template&lt;typename T&gt; ref class R{<br>public:<br>void F()<br>{ Console::WriteLine("hey"); }<br>}; <br>template&lt;&gt; ref class R&lt;int&gt;<br>{<br>public:<br>void F()<br>{ Console::WriteLine("int"); }<br>};</td>
        </tr>
    </tbody>
</table>
<br>　　你不能用泛型这样编码；否则，将产生：<br><br>　　编译错：error C2979: explicit specializations are not supported in generics<br><br>　　但可以在继承链中混合使用模板和泛型：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>generic&lt;typename T&gt; ref class Base<br>{<br>public:<br>void F1(T){}<br>};<br>template&lt;typename T&gt; ref class Derived : Base&lt;T&gt;<br>{<br>public:<br>void F2(T){}<br>};<br>//...<br>Derived&lt;int&gt; d;<br>d.F1(10);<br>d.F2(10);</td>
        </tr>
    </tbody>
</table>
<br>　　最后，你不能从一个泛型参数类型派生一个泛型类。<br><br>　　下列代码不会成功编译：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>generic&lt;typename T&gt; ref class R : T<br>{};</td>
        </tr>
    </tbody>
</table>
<br>　　error C3234: a generic class may not derive from a generic type parameter<br><br>　　模板让你这样做(好像你还不知道这些)：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>ref class Base{<br>public:<br>void F(){}<br>};<br>generic&lt;typename T&gt; ref class R : T<br>{};<br>//...<br>R&lt;Base&gt; r1;<br>r1.F();</td>
        </tr>
    </tbody>
</table>
<br>　　这样，当你下次遇到对泛型的贬谤时，你就知道该怎么做了。<br><br>　　6. STL/CLR<br><br>　　当大量使用STL的C++开发者转向.NET1/1.1时一定感觉非常别扭，他们中的许多可能会放弃并转回到原来的本机编码。从技术上讲，你能结合.NET类型(using gcroot)使用本机STL，但是产生的结果代码可能相当低效，更不用说是丑陋了：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>std::vector&lt; gcroot&lt;IntPtr&gt; &gt;* m_vec_hglobal;<br>//...<br>for each(gcroot&lt;IntPtr&gt; ptr in *m_vec_hglobal)<br>{ Marshal::FreeHGlobal(ptr);}</td>
        </tr>
    </tbody>
</table>
<br>　　大概VC++小组考虑到了这些并决定在Whidbey以后，他们会提供STL.NET（或STL/CLR）并可以单独从网上下载。<br><br>　　你可能问为什么？Stan Lippman，在他的MSDN文章(STL.NET Primer)中给出了3条原因：<br><br>　　&#183;可扩展性--STL设计把算法和容器隔离到自己的应用空间-也就是你可以有一组容器和一组算法，并且你能在任何一个容器上使用这些算法；同时你能在任何一个算法中使用这些容器。因此，如果你添加一种新的算法，你能在任何一种容器中使用它；同样，一个新的容器也可以与现有算法配合使用。<br><br>　　&#183;统一性--所有核心C++开发者集中在一起，汇集起他们精妙的STL专长，再使用他们的专长则轻车熟路。要较好地使用STL需要花费时间-然而一旦你掌握了它，你就有了在.NET世界中使用你的技巧的明显优势。不是吗？<br><br>　　&#183;性能--STL.NET通过使用实现泛型接口的托管模板实现。并且既然它的核心已用C++和托管模板编码，可以期盼它比在BCL上使用的泛型容器更具有性能优势。<br><br>　　使用过STL的人不需要任何示范，所以下面代码有益于以前没有使用过STL的人。<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>vector&lt;String^&gt; vecstr;<br>vecstr.push_back("wally");<br>vecstr.push_back("nish");<br>vecstr.push_back("smitha");<br>vecstr.push_back("nivi");<br>deque&lt;String^&gt; deqstr;<br>deqstr.push_back("wally");<br>deqstr.push_back("nish");<br>deqstr.push_back("smitha");<br>deqstr.push_back("nivi");</td>
        </tr>
    </tbody>
</table>
<br>　　我使用了两个STL.NET容器-vector和deque，并装满两个容器，使其看起来相同(在两个容器中都使用了push_back)。现在，我将在两个容器上使用replace算法-我们再次看到，这些代码是很相同的。<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>replace(vecstr.begin(), vecstr.end(),<br>gcnew String("nish"), gcnew String("jambo"));<br>replace(deqstr.begin(), deqstr.end(),<br>gcnew String("nish"), gcnew String("chris")); </td>
        </tr>
    </tbody>
</table>
<br>　　这里特别要注意的是我使用了"同样"的算法--replace并在两个不同STL容器上使用相同的函数调用。这是当Stan谈及"可扩展性"时的意思。下面我用一个简单函数来证明：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>template&lt;typename ForwardIterator&gt; void Capitalize(<br>ForwardIterator first，ForwardIterator end)<br>{<br>for(ForwardIterator it = first; it &lt; end; it++) <br>*it = (*it)-&gt;ToUpper(); <br>}</td>
        </tr>
    </tbody>
</table>
<br>　　它遍历一个System::String^容器并把其中的每个字符串转化为大写。<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>Capitalize(vecstr.begin(), vecstr.end());<br>Capitalize(deqstr.begin(), deqstr.end());<br>for(vector&lt;String^&gt;::iterator it = vecstr.begin(); <br>it &lt; vecstr.end(); it++)<br>Console::WriteLine(*it);<br>Console::WriteLine();<br>for(deque&lt;String^&gt;::iterator it = deqstr.begin(); <br>it &lt; deqstr.end(); it++)<br>Console::WriteLine(*it);</td>
        </tr>
    </tbody>
</table>
<br>　　上面我的算法能够与vector和deque容器工作良好。至此，不再细谈；否则，guru站上的STL爱好者们会对我群起攻击，而非STL人可能感到厌烦。如果你还没使用过STL，可以参考有关资料。<br><br>7. 熟悉的语法<br><br>　　开发者经常迷恋他们所用的编程语言，而很少是出于实用的目的。还记得当微软宣布不再为VB6提供官方支持时，VB6人的反抗吗？非VB6人对此可能非常震惊，而老道的VB6人早已为他们的语言作好葬礼准备了。事实上，如果VB.NET从来没被发明，多数VB6人将会离开.NET，因为C#将会对他们非常陌生，而它的祖先就是C++。如今，许多VB.NET人可能已经转向了C#，但是他们不会从VB6直接转向C#；VB.NET起到一个桥梁作用让他们的思想脱离开原来VB6思想。相应地，如果微软仅发行VB.NET(而没有C#)，那么.NET可能成为了新的面向对象VB，且带有一个更大的类库-C++社团的人可能对此嗤之以鼻-他们甚至不会麻烦地检验.NET基础类库。为什么任何使用一种特定语言的开发者会对另外一个团体的使用另外开发语言的开发者嗤之以鼻？这不是我要回答的问题。--要回答该问题也许要先回答为什么有的人喜欢威士忌，有的人喜欢可口可乐，而还有人喜欢牛奶。所有我要说的是，对开发者来说，语法家族是个大问题。<br><br>　　你认为对于一个具有C++背景的人，下面的代码具有怎样的直觉性？<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>char[] arr =new char[128];</td>
        </tr>
    </tbody>
</table>
<br>　　他/她可能回答的第一件事是，方括号放错了位置。下面这句又如何？<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>int y=arr.Length;</td>
        </tr>
    </tbody>
</table>
<br>　　"呀!"-最可能的反映。现在把下面与前面相比较：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>char natarr[128];<br>array&lt;char&gt;^ refarr=gcnew array&lt;char&gt;(128);<br>int y=refarr-&gt;Length;</td>
        </tr>
    </tbody>
</table>
<br>　　请注意声明一个本机数组和一个托管数组时的语法区别。这里不同的模板形式的语法可视化地告诫开发者这一事实--refarr并不是典型的C++数组而且它可能是某种CLI类的派生物(事实上确是如此)，所以极有可能可以把方法和属性应用于它。<br><br>　　C#的finalizer语法最有可能引起转向C#的C++程序员的混淆。请看见下列C#代码：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>class R<br>{ ~R(){} }</td>
        </tr>
    </tbody>
</table>
<br>　　好，这样~R看起来象一个析构器但实际是个finalizer。为什么？请与下面的C++代码比较：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>ref class R<br>{<br>~R(){ }<br>!R(){ }<br>};</td>
        </tr>
    </tbody>
</table>
<br>　　这里~R是析构器（实际上等价于一个析构器的Dispose模式-但对C++人员来说，这它的行为象个析构器）而新的!R语法是为finalizer建立的-这样就不再有混淆而且语法看上去也与本机C++相匹配。<br><br>　　请看一下C#泛型语法：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>class R&lt;T&gt;{};</td>
        </tr>
    </tbody>
</table>
<br>　　再请看一下C++的语法：<br><br>
<table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>generic&lt;typename T&gt; ref class R{};</td>
        </tr>
    </tbody>
</table>
<br>　　曾经使用过模板的人马上就看出这种C++语法，而C#语法不能保证其没有混淆性且也不直观。我的观点是，如果你以前具有C++背景，C++/CLI语法将最贴近于你以前所用。C#(以及J#)看上去象C++，但是还有相当多的极为使人烦火的奇怪语义差别而且如果你没有完全放弃C++，语法差别将永远不停地带给你混乱和挫折。从这种意义上说，我认为VB.NET更好些，至少它有自己唯一的语法，所以那些共用C++和VB.NET的人不会产生语法混乱。<br><br>　　8. 结论<br><br>　　最后，至于你用什么语言编程，这可能依赖许多因素——如：你在学校学习的是什么语言，你是用什么语言开发的现有代码仓库，是否你的客户对你有具体的语言要求等。本文的主要目的是帮助你确定使用C++/CLI的几个明确的场所--这里，它比另外CLI语言更具有明显优势。如果你开发的应用程序有90%的使用时间是涉及本机interop，为何还要考虑使用另外的而不是C++？如果你想开发一个通用集合，为什么仅把你自己限制在泛型上，而不是结合泛型和模板的优势呢？如果你已经用C++工作，为什么还要学习一种新的语言?我常觉得象C#和VB.NET这样的语言总是尽量向开发者隐藏CLR，而C++不仅让你品味CLR，甚至可以让你去亲吻CLR!&nbsp;<br></p><img src ="http://www.cppblog.com/mzty/aggbug/56531.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2008-07-18 22:12 <a href="http://www.cppblog.com/mzty/archive/2008/07/18/56531.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CLI与C#比较</title><link>http://www.cppblog.com/mzty/archive/2008/06/02/51878.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Mon, 02 Jun 2008 06:17:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2008/06/02/51878.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/51878.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2008/06/02/51878.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/51878.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/51878.html</trackback:ping><description><![CDATA[<br>来自：The Most Powerful Language for .NET Framework Programming&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://msdn.microsoft.com/en-us/library/ms379617(VS.80).aspx">http://msdn.microsoft.com/en-us/library/ms379617(VS.80).aspx</a><br><br><br>比较：<br>
<table class=dtTABLE borderColor=#00ccff cellSpacing=0 cellPadding=0 border=5>
    <tbody>
        <tr vAlign=top>
            <th width="25%">Description</th>
            <th width="37%">C++/CLI</th>
            <th width="38%">C#</th>
        </tr>
        <tr vAlign=top>
            <td width="25%">Allocate reference type</td>
            <td width="37%"><strong>ReferenceType^ h = gcnew ReferenceType;</strong></td>
            <td width="38%"><strong>ReferenceType h = new ReferenceType();</strong></td>
        </tr>
        <tr vAlign=top>
            <td width="25%">Allocate value type</td>
            <td width="37%"><strong>ValueType v(3, 4);</strong></td>
            <td width="38%"><strong>ValueType v = new ValueType(3, 4);</strong></td>
        </tr>
        <tr vAlign=top>
            <td width="25%">Reference type, stack semantics</td>
            <td width="37%"><strong>ReferenceType h;</strong></td>
            <td width="38%">N/A</td>
        </tr>
        <tr vAlign=top>
            <td width="25%">Calling <strong>Dispose</strong> method</td>
            <td width="37%"><strong>ReferenceType^ h = gcnew ReferenceType;</strong>
            <p><strong>delete h;</strong></p>
            </td>
            <td width="38%"><strong>ReferenceType h = new ReferenceType();</strong>
            <p><strong>((IDisposable)h).Dispose();</strong></p>
            </td>
        </tr>
        <tr vAlign=top>
            <td width="25%">Implementing <strong>Dispose</strong> method</td>
            <td width="37%"><strong>~TypeName() {}</strong></td>
            <td width="38%"><strong>void IDisposable.Dispose() {}</strong></td>
        </tr>
        <tr vAlign=top>
            <td width="25%">Implementing <strong>Finalize</strong> method</td>
            <td width="37%"><strong>!TypeName() {}</strong></td>
            <td width="38%"><strong>~TypeName() {}</strong></td>
        </tr>
        <tr vAlign=top>
            <td width="25%">Boxing</td>
            <td width="37%"><strong>int^ h = 123;</strong></td>
            <td width="38%"><strong>object h = 123;</strong></td>
        </tr>
        <tr vAlign=top>
            <td width="25%">Unboxing</td>
            <td width="37%"><strong>int^ hi = 123;</strong>
            <p><strong>int c = *hi;</strong></p>
            </td>
            <td width="38%"><strong>object h = 123;</strong>
            <p><strong>int i = (int) h;</strong></p>
            </td>
        </tr>
        <tr vAlign=top>
            <td width="25%">Reference type definition</td>
            <td width="37%"><strong>ref class ReferenceType {};</strong>
            <p><strong>ref struct ReferenceType {};</strong></p>
            </td>
            <td width="38%"><strong>class ReferenceType {}</strong></td>
        </tr>
        <tr vAlign=top>
            <td width="25%">Value type definition</td>
            <td width="37%"><strong>value class ValueType {};</strong>
            <p><strong>value struct ValueType {};</strong></p>
            </td>
            <td width="38%"><strong>struct ValueType {}</strong></td>
        </tr>
        <tr vAlign=top>
            <td width="25%">Using properties</td>
            <td width="37%"><strong>h.Prop = 123;</strong>
            <p><strong>int v = h.Prop;</strong></p>
            </td>
            <td width="38%"><strong>h.Prop = 123;</strong>
            <p><strong>int v = h.Prop;</strong></p>
            </td>
        </tr>
        <tr vAlign=top>
            <td width="25%">Property definition</td>
            <td width="37%"><strong>property String^ Name <br>{<br>&nbsp;&nbsp;&nbsp; String^ get()<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return m_value;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; void set(String^ value)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_value = value;<br>&nbsp;&nbsp;&nbsp; }<br>}</strong></td>
            <td width="38%"><strong>string Name <br>{<br>&nbsp;&nbsp;&nbsp; get<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return m_name;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; set<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_name = value;<br>&nbsp;&nbsp;&nbsp; }<br>}</strong></td>
        </tr>
    </tbody>
</table>
<br>thanks<img src ="http://www.cppblog.com/mzty/aggbug/51878.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2008-06-02 14:17 <a href="http://www.cppblog.com/mzty/archive/2008/06/02/51878.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CLI中native的string和System::String转化</title><link>http://www.cppblog.com/mzty/archive/2008/03/12/44280.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Wed, 12 Mar 2008 08:47:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2008/03/12/44280.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/44280.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2008/03/12/44280.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/44280.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/44280.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一 实例 （代码下载 http://www.cppblog.com/Files/mzty/SystemStringAndNativeString.rar）nativeclass.h#pragma&nbsp;once&nbsp;#include&nbsp;&lt;string&gt;#include&nbsp;&lt;iostream&gt;class&nbsp;NativeClass{publ...&nbsp;&nbsp;<a href='http://www.cppblog.com/mzty/archive/2008/03/12/44280.html'>阅读全文</a><img src ="http://www.cppblog.com/mzty/aggbug/44280.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2008-03-12 16:47 <a href="http://www.cppblog.com/mzty/archive/2008/03/12/44280.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#的Form通过CLI调用C++的DLL</title><link>http://www.cppblog.com/mzty/archive/2007/12/25/39610.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Tue, 25 Dec 2007 11:14:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2007/12/25/39610.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/39610.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2007/12/25/39610.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/39610.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/39610.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一 方法&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C#的project调用C++的DLL，一般也有3中方法：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1）最简单的方法，通过PInvoke，但是只能调用全局function，不能调用Class。&nbsp;&nbsp;&...&nbsp;&nbsp;<a href='http://www.cppblog.com/mzty/archive/2007/12/25/39610.html'>阅读全文</a><img src ="http://www.cppblog.com/mzty/aggbug/39610.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2007-12-25 19:14 <a href="http://www.cppblog.com/mzty/archive/2007/12/25/39610.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>NativeC++通过CLI调用C#的Form</title><link>http://www.cppblog.com/mzty/archive/2007/12/25/39555.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Tue, 25 Dec 2007 02:51:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2007/12/25/39555.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/39555.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2007/12/25/39555.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/39555.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/39555.html</trackback:ping><description><![CDATA[<br>一 调用方法<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Native C++的project调用C#的DLL，一般有3中方法：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1）通过COM封装<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2）通过CLI/C++的Wrapper<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3)&nbsp; 在VS中可以直接修改NativeC++的project或是部分文件为使用CLR来调用C#的DLL<br><br>二 实例<br>1）C#的一个MyForm类，有public函数ShowMyForm（）<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Collections.Generic;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Text;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Windows.Forms;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><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;CsharpDLL<br><img id=Codehighlighter1_116_1454_Open_Image onclick="this.style.display='none'; Codehighlighter1_116_1454_Open_Text.style.display='none'; Codehighlighter1_116_1454_Closed_Image.style.display='inline'; Codehighlighter1_116_1454_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_116_1454_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_116_1454_Closed_Text.style.display='none'; Codehighlighter1_116_1454_Open_Image.style.display='inline'; Codehighlighter1_116_1454_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_116_1454_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_116_1454_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: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;MyForm&nbsp;:&nbsp;Form<br><img id=Codehighlighter1_153_1452_Open_Image onclick="this.style.display='none'; Codehighlighter1_153_1452_Open_Text.style.display='none'; Codehighlighter1_153_1452_Closed_Image.style.display='inline'; Codehighlighter1_153_1452_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_153_1452_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_153_1452_Closed_Text.style.display='none'; Codehighlighter1_153_1452_Open_Image.style.display='inline'; Codehighlighter1_153_1452_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_1452_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_1452_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: #0000ff">private</span><span style="COLOR: #000000">&nbsp;Button&nbsp;button1;<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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;ShowMyForm()<br><img id=Codehighlighter1_229_270_Open_Image onclick="this.style.display='none'; Codehighlighter1_229_270_Open_Text.style.display='none'; Codehighlighter1_229_270_Closed_Image.style.display='inline'; Codehighlighter1_229_270_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_229_270_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_229_270_Closed_Text.style.display='none'; Codehighlighter1_229_270_Open_Image.style.display='inline'; Codehighlighter1_229_270_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_229_270_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_229_270_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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.ShowDialog();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;MyForm()<br><img id=Codehighlighter1_304_448_Open_Image onclick="this.style.display='none'; Codehighlighter1_304_448_Open_Text.style.display='none'; Codehighlighter1_304_448_Closed_Image.style.display='inline'; Codehighlighter1_304_448_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_304_448_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_304_448_Closed_Text.style.display='none'; Codehighlighter1_304_448_Open_Image.style.display='inline'; Codehighlighter1_304_448_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_304_448_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_304_448_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;&nbsp;&nbsp;&nbsp;&nbsp;InitializeComponent();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.Text&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MyForm</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.StartPosition&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;FormStartPosition.CenterScreen;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;InitializeComponent()<br><img id=Codehighlighter1_501_1303_Open_Image onclick="this.style.display='none'; Codehighlighter1_501_1303_Open_Text.style.display='none'; Codehighlighter1_501_1303_Closed_Image.style.display='inline'; Codehighlighter1_501_1303_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_501_1303_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_501_1303_Closed_Text.style.display='none'; Codehighlighter1_501_1303_Open_Image.style.display='inline'; Codehighlighter1_501_1303_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_501_1303_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_501_1303_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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;System.Windows.Forms.Button();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.SuspendLayout();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;button1<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1.Location&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;System.Drawing.Point(</span><span style="COLOR: #000000">110</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">74</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1.Name&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">button1</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1.Size&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;System.Drawing.Size(</span><span style="COLOR: #000000">75</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">23</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1.TabIndex&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1.Text&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">TestMessageBox</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1.UseVisualStyleBackColor&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1.Click&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;System.EventHandler(</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1_Click);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;MyForm<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.ClientSize&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;System.Drawing.Size(</span><span style="COLOR: #000000">292</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">266</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.Controls.Add(</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.Name&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MyForm</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.ResumeLayout(</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;button1_Click(</span><span style="COLOR: #0000ff">object</span><span style="COLOR: #000000">&nbsp;sender,&nbsp;EventArgs&nbsp;e)<br><img id=Codehighlighter1_1377_1446_Open_Image onclick="this.style.display='none'; Codehighlighter1_1377_1446_Open_Text.style.display='none'; Codehighlighter1_1377_1446_Closed_Image.style.display='inline'; Codehighlighter1_1377_1446_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_1377_1446_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1377_1446_Closed_Text.style.display='none'; Codehighlighter1_1377_1446_Open_Image.style.display='inline'; Codehighlighter1_1377_1446_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_1377_1446_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_1377_1446_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;&nbsp;&nbsp;&nbsp;&nbsp;MessageBox.Show(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello,&nbsp;i&nbsp;am&nbsp;a&nbsp;Csharp&nbsp;Form!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/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>
<br>2）C#的exe调用<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Collections.Generic;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Text;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><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;CsharpTest<br><img id=Codehighlighter1_89_411_Open_Image onclick="this.style.display='none'; Codehighlighter1_89_411_Open_Text.style.display='none'; Codehighlighter1_89_411_Closed_Image.style.display='inline'; Codehighlighter1_89_411_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_89_411_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_89_411_Closed_Text.style.display='none'; Codehighlighter1_89_411_Open_Image.style.display='inline'; Codehighlighter1_89_411_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_89_411_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_89_411_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: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Program<br><img id=Codehighlighter1_113_409_Open_Image onclick="this.style.display='none'; Codehighlighter1_113_409_Open_Text.style.display='none'; Codehighlighter1_113_409_Closed_Image.style.display='inline'; Codehighlighter1_113_409_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_113_409_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_113_409_Closed_Text.style.display='none'; Codehighlighter1_113_409_Open_Image.style.display='inline'; Codehighlighter1_113_409_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_113_409_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_113_409_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: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Main(</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">[]&nbsp;args)<br><img id=Codehighlighter1_163_403_Open_Image onclick="this.style.display='none'; Codehighlighter1_163_403_Open_Text.style.display='none'; Codehighlighter1_163_403_Closed_Image.style.display='inline'; Codehighlighter1_163_403_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_163_403_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_163_403_Closed_Text.style.display='none'; Codehighlighter1_163_403_Open_Image.style.display='inline'; Codehighlighter1_163_403_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_163_403_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_163_403_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;&nbsp;&nbsp;&nbsp;&nbsp;System.Console.WriteLine(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Csharp&nbsp;main&nbsp;funtion&nbsp;start:</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CsharpDLL.MyForm&nbsp;myForm&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;CsharpDLL.MyForm();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myForm.ShowMyForm();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.Console.WriteLine(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Csharp&nbsp;main&nbsp;function&nbsp;end!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/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>
<br>3）CLI/C++的warpper，DLLexport函数CallCsharpForm（），此函数中调用C#的MyForm<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">CPPCLIPROXYDLLFORCSHARPDLL_API&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;CallCsharpForm();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#</span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">../debug/CsharpDll.dll</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>CPPCLIPROXYDLLFORCSHARPDLL_API&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;CallCsharpForm()<br><img id=Codehighlighter1_141_222_Open_Image onclick="this.style.display='none'; Codehighlighter1_141_222_Open_Text.style.display='none'; Codehighlighter1_141_222_Closed_Image.style.display='inline'; Codehighlighter1_141_222_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_141_222_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_141_222_Closed_Text.style.display='none'; Codehighlighter1_141_222_Open_Image.style.display='inline'; Codehighlighter1_141_222_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_141_222_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_141_222_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;CsharpDLL::MyForm</span><span style="COLOR: #000000">^</span><span style="COLOR: #000000">&nbsp;myForm&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;gcnew&nbsp;CsharpDLL::MyForm();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;myForm</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">ShowMyForm();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br>4）NativeC++的exe调用CLI的Wrapper来间接的调用MyForm<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">stdafx.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#pragma&nbsp;comment(lib,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">../debug/CppCLIProxyDLLForCsharpDLL.lib</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;CallCsharpForm();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;_tmain(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;_TCHAR</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;argv[])<br><img id=Codehighlighter1_166_300_Open_Image onclick="this.style.display='none'; Codehighlighter1_166_300_Open_Text.style.display='none'; Codehighlighter1_166_300_Closed_Image.style.display='inline'; Codehighlighter1_166_300_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_166_300_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_166_300_Closed_Text.style.display='none'; Codehighlighter1_166_300_Open_Image.style.display='inline'; Codehighlighter1_166_300_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_166_300_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_166_300_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;Cpp&nbsp;Main&nbsp;function&nbsp;start:</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;CallCsharpForm();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;Cpp&nbsp;Main&nbsp;function&nbsp;end!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<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;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br>三 总结<br>要调试最好修改编译选项为Mixed。<br><br>代码下载： <a href="http://www.cppblog.com/Files/mzty/CppCallCsharpByCLI.rar">http://www.cppblog.com/Files/mzty/CppCallCsharpByCLI.rar</a><br><img src ="http://www.cppblog.com/mzty/aggbug/39555.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2007-12-25 10:51 <a href="http://www.cppblog.com/mzty/archive/2007/12/25/39555.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CLI/C++中混合类的使用</title><link>http://www.cppblog.com/mzty/archive/2007/12/24/39517.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Mon, 24 Dec 2007 09:47:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2007/12/24/39517.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/39517.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2007/12/24/39517.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/39517.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/39517.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一 混合类所谓混合类是指CLI/C++中native的Class中可以包含CLR对象，CLR的class也可以包含Naitve的对象。1）native的class中包含CLR对象，必须通过gcroot&lt;&gt;或auto_gcroot&lt;&gt;。2）CLR中的class中包含native的对象，必须是指针，也可以使用高手写的CAutoNativePtr智能指针。注意：C#中不能...&nbsp;&nbsp;<a href='http://www.cppblog.com/mzty/archive/2007/12/24/39517.html'>阅读全文</a><img src ="http://www.cppblog.com/mzty/aggbug/39517.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2007-12-24 17:47 <a href="http://www.cppblog.com/mzty/archive/2007/12/24/39517.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个CLI/C++的DLL同时被C#的exe和NativeC++的exe调用</title><link>http://www.cppblog.com/mzty/archive/2007/12/20/39165.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Thu, 20 Dec 2007 14:47:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2007/12/20/39165.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/39165.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2007/12/20/39165.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/39165.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/39165.html</trackback:ping><description><![CDATA[<br>&nbsp;一&nbsp;引子<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1）使用VS2005，Native C++，C#，CLI/C++。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2）主要介绍CLI/C++和Native C++, C#的交互，最总能够实现以CLI/C++为中介的Native C++与C#的互调。<br><br>&nbsp;二 实例<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1）实现一个CLI/C++的Dll，在此Dll中包含一个RefClass能够被C#的exe调用。（实现过程：在VS中建立C++ CLR Class library 的一个Project，然后增加一个类RefClass）代码如下：<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;refclass.h文件：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<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">#pragma&nbsp;once&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><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;ClrCppDll&nbsp;<br><img id=Codehighlighter1_36_196_Open_Image onclick="this.style.display='none'; Codehighlighter1_36_196_Open_Text.style.display='none'; Codehighlighter1_36_196_Closed_Image.style.display='inline'; Codehighlighter1_36_196_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_36_196_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_36_196_Closed_Text.style.display='none'; Codehighlighter1_36_196_Open_Image.style.display='inline'; Codehighlighter1_36_196_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_36_196_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_36_196_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: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">ref</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;RefClass<br><img id=Codehighlighter1_66_193_Open_Image onclick="this.style.display='none'; Codehighlighter1_66_193_Open_Text.style.display='none'; Codehighlighter1_66_193_Closed_Image.style.display='inline'; Codehighlighter1_66_193_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_66_193_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_66_193_Closed_Text.style.display='none'; Codehighlighter1_66_193_Open_Image.style.display='inline'; Codehighlighter1_66_193_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_66_193_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_66_193_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: #0000ff">public</span><span style="COLOR: #000000">:<br><img id=Codehighlighter1_89_90_Open_Image onclick="this.style.display='none'; Codehighlighter1_89_90_Open_Text.style.display='none'; Codehighlighter1_89_90_Closed_Image.style.display='inline'; Codehighlighter1_89_90_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_89_90_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_89_90_Closed_Text.style.display='none'; Codehighlighter1_89_90_Open_Image.style.display='inline'; Codehighlighter1_89_90_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RefClass()</span><span id=Codehighlighter1_89_90_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_89_90_Open_Text><span style="COLOR: #000000">{}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RefClass(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;_x,&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;_y)&nbsp;:&nbsp;x(_x),&nbsp;y(_y)<br><img id=Codehighlighter1_136_140_Open_Image onclick="this.style.display='none'; Codehighlighter1_136_140_Open_Text.style.display='none'; Codehighlighter1_136_140_Closed_Image.style.display='inline'; Codehighlighter1_136_140_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_136_140_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_136_140_Closed_Text.style.display='none'; Codehighlighter1_136_140_Open_Image.style.display='inline'; Codehighlighter1_136_140_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_136_140_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_136_140_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;PrintSelf();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;x;<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: #0000ff">int</span><span style="COLOR: #000000">&nbsp;y;<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/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;refclass.cpp文件：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">stdafx.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">refclass.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;System;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;ClrCppDll;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;RefClass::PrintSelf()<br><img id=Codehighlighter1_122_270_Open_Image onclick="this.style.display='none'; Codehighlighter1_122_270_Open_Text.style.display='none'; Codehighlighter1_122_270_Closed_Image.style.display='inline'; Codehighlighter1_122_270_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_122_270_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_122_270_Closed_Text.style.display='none'; Codehighlighter1_122_270_Open_Image.style.display='inline'; Codehighlighter1_122_270_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_122_270_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_122_270_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;System::Console::WriteLine(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">hello,&nbsp;i&nbsp;am&nbsp;a&nbsp;ref&nbsp;cpp&nbsp;class</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;System::Console::WriteLine(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">x&nbsp;is&nbsp;{0}</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,x);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;System::Console::WriteLine(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">y&nbsp;is&nbsp;{0}</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,y);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2）能够调用上面第1）步中的CLI/C++的Dll中class的C#的exe。（实现过程：在VS建立C#的console Application，然后reference 前面的1)生成的Dll）代码如下：<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.cs文件：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Collections.Generic;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Text;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><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;CsharpTest<br><img id=Codehighlighter1_89_286_Open_Image onclick="this.style.display='none'; Codehighlighter1_89_286_Open_Text.style.display='none'; Codehighlighter1_89_286_Closed_Image.style.display='inline'; Codehighlighter1_89_286_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_89_286_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_89_286_Closed_Text.style.display='none'; Codehighlighter1_89_286_Open_Image.style.display='inline'; Codehighlighter1_89_286_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_89_286_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_89_286_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: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Program<br><img id=Codehighlighter1_113_284_Open_Image onclick="this.style.display='none'; Codehighlighter1_113_284_Open_Text.style.display='none'; Codehighlighter1_113_284_Closed_Image.style.display='inline'; Codehighlighter1_113_284_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_113_284_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_113_284_Closed_Text.style.display='none'; Codehighlighter1_113_284_Open_Image.style.display='inline'; Codehighlighter1_113_284_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_113_284_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_113_284_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: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Main(</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">[]&nbsp;args)<br><img id=Codehighlighter1_163_278_Open_Image onclick="this.style.display='none'; Codehighlighter1_163_278_Open_Text.style.display='none'; Codehighlighter1_163_278_Closed_Image.style.display='inline'; Codehighlighter1_163_278_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_163_278_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_163_278_Closed_Text.style.display='none'; Codehighlighter1_163_278_Open_Image.style.display='inline'; Codehighlighter1_163_278_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_163_278_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_163_278_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;&nbsp;&nbsp;&nbsp;&nbsp;ClrCppDll.RefClass&nbsp;refClass&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;ClrCppDll.RefClass(</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;refClass.PrintSelf();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br><span style="BACKGROUND-COLOR: #ff0000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;上面2步的代码下载</span>：<a href="http://www.cppblog.com/Files/mzty/CSharpCPPCLI1.rar">http://www.cppblog.com/Files/mzty/CSharpCPPCLI1.rar</a>&nbsp;（实现CLI/C++的dll能够被C#调用）<br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp; 3）对1）实现的CLI/C++的Dll中增加能够被Native C++调用的NativeClass。代码如下：<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NativeClass.h文件：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">#pragma&nbsp;once<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><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;ClrCppDll<br><img id=Codehighlighter1_34_207_Open_Image onclick="this.style.display='none'; Codehighlighter1_34_207_Open_Text.style.display='none'; Codehighlighter1_34_207_Closed_Image.style.display='inline'; Codehighlighter1_34_207_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_34_207_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_34_207_Closed_Text.style.display='none'; Codehighlighter1_34_207_Open_Image.style.display='inline'; Codehighlighter1_34_207_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_34_207_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_34_207_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: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;NativeClass<br><img id=Codehighlighter1_63_204_Open_Image onclick="this.style.display='none'; Codehighlighter1_63_204_Open_Text.style.display='none'; Codehighlighter1_63_204_Closed_Image.style.display='inline'; Codehighlighter1_63_204_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_63_204_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_63_204_Closed_Text.style.display='none'; Codehighlighter1_63_204_Open_Image.style.display='inline'; Codehighlighter1_63_204_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_63_204_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_63_204_Open_Text><span style="COLOR: #000000">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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: #0000ff">public</span><span style="COLOR: #000000">:<br><img id=Codehighlighter1_93_94_Open_Image onclick="this.style.display='none'; Codehighlighter1_93_94_Open_Text.style.display='none'; Codehighlighter1_93_94_Closed_Image.style.display='inline'; Codehighlighter1_93_94_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_93_94_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_93_94_Closed_Text.style.display='none'; Codehighlighter1_93_94_Open_Image.style.display='inline'; Codehighlighter1_93_94_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NativeClass()</span><span id=Codehighlighter1_93_94_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_93_94_Open_Text><span style="COLOR: #000000">{}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NativeClass(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;_x,&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;_y)&nbsp;:&nbsp;x(_x),&nbsp;y(_y)<br><img id=Codehighlighter1_145_146_Open_Image onclick="this.style.display='none'; Codehighlighter1_145_146_Open_Text.style.display='none'; Codehighlighter1_145_146_Closed_Image.style.display='inline'; Codehighlighter1_145_146_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_145_146_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_145_146_Closed_Text.style.display='none'; Codehighlighter1_145_146_Open_Image.style.display='inline'; Codehighlighter1_145_146_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_145_146_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BOR