﻿<?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; 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_145_146_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><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">void</span><span style="COLOR: #000000">&nbsp;printSelf();<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">:<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">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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;y;&nbsp;&nbsp;&nbsp;&nbsp;<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;NativeClass.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">&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>#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">nativeclass.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;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;NativeClass::printSelf()<br><img id=Codehighlighter1_124_257_Open_Image onclick="this.style.display='none'; Codehighlighter1_124_257_Open_Text.style.display='none'; Codehighlighter1_124_257_Closed_Image.style.display='inline'; Codehighlighter1_124_257_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_124_257_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_124_257_Closed_Text.style.display='none'; Codehighlighter1_124_257_Open_Image.style.display='inline'; Codehighlighter1_124_257_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_124_257_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_124_257_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">hello,i&nbsp;am&nbsp;a&nbsp;native&nbsp;cpp&nbsp;class!</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;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">x&nbsp;is&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">x</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;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">y&nbsp;is&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">y</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="BACKGROUND-COLOR: #ff0000">问题：</span> <span style="COLOR: red">如果我们直接在NativeC++的exe调用上面CLI/C++中的NativeClass，会有问题，Error&nbsp;1&nbsp;error C3381: 'CppClrDll::NativeClass' : assembly access specifiers are only available in code compiled with a /clr option&nbsp;d:\cppandcsharpinteractivetest\csharpcppcli\clrcppdll\nativeclass.h&nbsp;8，这是为什么那，我们想想我们一般的Native C++的DLL的调用，都要将要被调用的Class或funtion导出才可以调用，想到这里我们也对我们的NativeClass进行导出。（怎么导出可以看下面的代码）但是当增加了对NativeClass的导出，调用的时候仍然有上面的error，Error&nbsp;1&nbsp;error C3381: 'CppClrDll::NativeClass' : assembly access specifiers are only available in code compiled with a /clr option&nbsp;d:\cppandcsharpinteractivetest\csharpcppcli\clrcppdll\nativeclass.h&nbsp;9，最后只有查找资料（没有找到）问别人（没有问到），最后想到使用导出函数试试，一试果然可行啊，哈哈哈，so Happy</span>！<span style="COLOR: #00ccff">其实后来发现是我加的导出__declspec(dllexport)的位置不对，应该是在class关键字后面，总之导出类也是可以的。</span>导出类的代码可以下载新的sample，增加导出和导出的函数代码如下：<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (导出不久需要下面的2文件，还的定义宏 CLR_CPP_DLL在编译选项中，或直接写在文件中)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clrcppdll.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: #008000">//</span><span style="COLOR: #008000">&nbsp;ClrCppDll.h</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#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>#ifdef&nbsp;CLR_CPP_DLL<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;DLLIMPEXP&nbsp;__declspec(dllexport)</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">#else</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;DLLIMPEXP</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">#endif</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">namespace</span><span style="COLOR: #000000">&nbsp;ClrCppDll&nbsp;<br><img id=Codehighlighter1_142_190_Open_Image onclick="this.style.display='none'; Codehighlighter1_142_190_Open_Text.style.display='none'; Codehighlighter1_142_190_Closed_Image.style.display='inline'; Codehighlighter1_142_190_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_142_190_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_142_190_Closed_Text.style.display='none'; Codehighlighter1_142_190_Open_Image.style.display='inline'; Codehighlighter1_142_190_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_142_190_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_142_190_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;DLLIMPEXP&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;&nbsp;CallNativeClassPrintSelf();&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clrcppdll.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: #008000">//</span><span style="COLOR: #008000">&nbsp;This&nbsp;is&nbsp;the&nbsp;main&nbsp;DLL&nbsp;file.</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#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">NativeClass.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">ClrCppDll.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>DLLIMPEXP&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;&nbsp;ClrCppDll::CallNativeClassPrintSelf()<br><img id=Codehighlighter1_154_212_Open_Image onclick="this.style.display='none'; Codehighlighter1_154_212_Open_Text.style.display='none'; Codehighlighter1_154_212_Closed_Image.style.display='inline'; Codehighlighter1_154_212_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_154_212_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_154_212_Closed_Text.style.display='none'; Codehighlighter1_154_212_Open_Image.style.display='inline'; Codehighlighter1_154_212_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_154_212_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_154_212_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;ClrCppDll::NativeClass&nbsp;test(</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">20</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;test.printSelf();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4）建立一个NativeC++的exe来调用1）生成的CLI/C++的Dll中的3）增加的NativeClass（实现过程：建立一个Native C++的console application）代码如下：<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cpptest.cpp文件：（经过上一步问题的反复折磨，终于搞定）（同时别忘了要在编译选项中指定lib和lib的路径）<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: #008000">//</span><span style="COLOR: #008000">&nbsp;CppTest.cpp&nbsp;:&nbsp;Defines&nbsp;the&nbsp;entry&nbsp;point&nbsp;for&nbsp;the&nbsp;console&nbsp;application.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#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">../ClrCppDll/clrcppdll.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">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_168_280_Open_Image onclick="this.style.display='none'; Codehighlighter1_168_280_Open_Text.style.display='none'; Codehighlighter1_168_280_Closed_Image.style.display='inline'; Codehighlighter1_168_280_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_168_280_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_168_280_Closed_Text.style.display='none'; Codehighlighter1_168_280_Open_Image.style.display='inline'; Codehighlighter1_168_280_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_168_280_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_168_280_Open_Text><span style="COLOR: #000000">{<br><img id=Codehighlighter1_171_226_Open_Image onclick="this.style.display='none'; Codehighlighter1_171_226_Open_Text.style.display='none'; Codehighlighter1_171_226_Closed_Image.style.display='inline'; Codehighlighter1_171_226_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_171_226_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_171_226_Closed_Text.style.display='none'; Codehighlighter1_171_226_Open_Image.style.display='inline'; Codehighlighter1_171_226_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_171_226_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id=Codehighlighter1_171_226_Open_Text><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">ClrCppDll::NativeClass&nbsp;test(5,6);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;test.PrintSelf();</span><span style="COLOR: #008000">*/</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;ClrCppDll::CallNativeClassPrintSelf();<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>&nbsp;&nbsp;&nbsp;上面四步总代码下载：<a href="http://www.cppblog.com/Files/mzty/CSharpCPPCLI2.rar">http://www.cppblog.com/Files/mzty/CSharpCPPCLI2.rar</a>&nbsp;（实现CLI/C++的dll同时被Native C++和C#的调用）<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5）扩展，增加在NativeClass中调用RefClass的funtion, 和RefClass中调用NativeClass的function。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;代码下载：<a href="http://www.cppblog.com/Files/mzty/CSharpCPPCLI3.rar">http://www.cppblog.com/Files/mzty/CSharpCPPCLI3.rar</a>&nbsp;（最后代码下载，包含NativeClass与RefClass的互调）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.cppblog.com/Files/mzty/CSharpCPPCLI32.zip">http://www.cppblog.com/Files/mzty/CSharpCPPCLI32.zip</a>&nbsp;（包含native class的导出也调用）<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;三 总结<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1) CLI/C++中如果想导出让NativeC++使用，则最好导出函数,也可以导出类。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2) CLI/C++的DLL可以没有像一般的NativeC++的Dll中的DllMain（）函数。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3) CLI/C++如果想导出让C#使用，则一般是ref class。<br><br><br><br><br><br><br><br><img src ="http://www.cppblog.com/mzty/aggbug/39165.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-20 22:47 <a href="http://www.cppblog.com/mzty/archive/2007/12/20/39165.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#通过C++/CLI调用C++DLL</title><link>http://www.cppblog.com/mzty/archive/2007/06/04/25524.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Mon, 04 Jun 2007 14:59:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2007/06/04/25524.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/25524.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2007/06/04/25524.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/25524.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/25524.html</trackback:ping><description><![CDATA[<br>只要你会C++/CLI就比较容易哦，或者说只要你会C++和C#学起来也是很快的哦！～<br><br><br><br>大家可以先参考，以后有时间加再写哦～<br><br><br>参考：<a href="http://www.codeproject.com/csharp/marshalCPPclass.asp">http://www.codeproject.com/csharp/marshalCPPclass.asp</a><br><br><br>
<img src ="http://www.cppblog.com/mzty/aggbug/25524.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-06-04 22:59 <a href="http://www.cppblog.com/mzty/archive/2007/06/04/25524.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++与.NET中基础类型的对应及转化</title><link>http://www.cppblog.com/mzty/archive/2007/05/29/25062.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Tue, 29 May 2007 05:55:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2007/05/29/25062.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/25062.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2007/05/29/25062.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/25062.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/25062.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 前言:为了介绍C#写界面，C++写算法的快捷交互开发方式，首先介绍c++，C#内部的DLL，COM调用.一，基础类型二，字符类型/***Author&nbsp;-&nbsp;Nishant&nbsp;SivakumarCopyright(C)&nbsp;-&nbsp;Nishant&nbsp;Sivakumar&nbsp;2005***/#pragma&nbsp;once#include&nb...&nbsp;&nbsp;<a href='http://www.cppblog.com/mzty/archive/2007/05/29/25062.html'>阅读全文</a><img src ="http://www.cppblog.com/mzty/aggbug/25062.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-05-29 13:55 <a href="http://www.cppblog.com/mzty/archive/2007/05/29/25062.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++/CLI</title><link>http://www.cppblog.com/mzty/archive/2007/05/29/25059.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Tue, 29 May 2007 05:38:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2007/05/29/25059.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/25059.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2007/05/29/25059.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/25059.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/25059.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 前言:为了介绍C#写界面，C++写算法的快捷交互开发方式，首先介绍c++，C#内部的DLL，COM调用.一，概念C++/CLI,结合和Native C++的.Net的特性，使我们可以在C++/CLI中更方便的使用Native C++和.Net资源，更快捷的开发，所以有人说C++/CLI是有史以来最强大的语言，但是强大也有他的弊端，就是复杂。也正是因为他的复杂所以许多C++的开发人员转到。net的时...&nbsp;&nbsp;<a href='http://www.cppblog.com/mzty/archive/2007/05/29/25059.html'>阅读全文</a><img src ="http://www.cppblog.com/mzty/aggbug/25059.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-05-29 13:38 <a href="http://www.cppblog.com/mzty/archive/2007/05/29/25059.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#界面，C++算法</title><link>http://www.cppblog.com/mzty/archive/2007/04/16/22064.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Mon, 16 Apr 2007 14:41:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2007/04/16/22064.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/22064.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2007/04/16/22064.html#Feedback</comments><slash:comments>16</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/22064.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/22064.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/mzty/archive/2007/04/16/22064.html'>阅读全文</a><img src ="http://www.cppblog.com/mzty/aggbug/22064.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-04-16 22:41 <a href="http://www.cppblog.com/mzty/archive/2007/04/16/22064.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Managed c++与c++\CLI的区别(实例)</title><link>http://www.cppblog.com/mzty/archive/2006/08/18/11397.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Fri, 18 Aug 2006 02:58:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2006/08/18/11397.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/11397.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2006/08/18/11397.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/11397.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/11397.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1 Managed c++ (使用vs2002,2003,建立visual c++下的console application(.net ) project,project还有各种类型)    注: 此时的project setting里一定是 :using Managed Extenstions -&gt;Yes简单实例#using &lt;mscorlib.dll&gt;using namesp...&nbsp;&nbsp;<a href='http://www.cppblog.com/mzty/archive/2006/08/18/11397.html'>阅读全文</a><img src ="http://www.cppblog.com/mzty/aggbug/11397.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2006-08-18 10:58 <a href="http://www.cppblog.com/mzty/archive/2006/08/18/11397.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Visual C++ .NET编程：托管C++概述</title><link>http://www.cppblog.com/mzty/archive/2006/08/18/11393.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Fri, 18 Aug 2006 02:18:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2006/08/18/11393.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/11393.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2006/08/18/11393.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/11393.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/11393.html</trackback:ping><description><![CDATA[2000年6月，Microsoft推出了“Microsoft.NET下一代互联网软件和服务战略”，引起IT行业的广泛关注。2000年9月，Microsoft在旧金山发布了Enterprise 2000。同月，Microsoft原总裁兼首席执行官鲍尔默来到中国就“下一代互联网”的主题进行演讲，在中国掀起了一股“.NET旋风”。2000年11月，Microsoft在Comdex计算机大展上发布了Visual Studio.NET软件，并展示了其.NET发展战略的框架体系和开发工具的相关特性，全面加速了Microsoft以.NET技术进军市场的步伐。 <br /><br />　　Microsoft的.NET战略意味着：Microsoft以及在Microsoft平台上的开发者将会制造服务，而不是制造软件。在未来几年之内，Microsoft将陆续发布有关.NET的平台和工具，用于在因特网上开发Web服务。那时，工作在.NET上的用户、开发人员和IT工作人员都不再购买软件、安装软件和维护软件。取而代之的是，他们将定制服务，软件会自动安装，所有的维护和升级也会通过互联网进行。“Microsoft.NET 代表了一个集合、一个环境、一个可以作为平台支持下一代Internet的可编程结构。”这就是鲍尔默对.NET的描述。<br /><br /><table width="80%" align="center"><tbody><tr><td><a href="http://book.yesky.com/vc/vc2.htm" target="_blank"></a></td></tr></tbody></table><br />　　作为.NET的最新特性组成部分，Microsoft .NET Framework是一个用于构建，部署和运行Web服务及应用程序的平台。它为将现有投资与下一代应用程序和服务的集成提供了高产的，基于标准的，多语言环境，同时它还用于解决Internet级应用程序的部署和操作问题。.NET框架包含三个主要部分：通用语言运行时，一组层次化的统一的类库，及组件化版本的动态服务器主页(称为ASP.NET)。<br /><br />　　用于开发.NET Framework的语言有Visual C#、VB.NET和C++托管扩展(Managed Extensions for C++)。其中C#是开发.NET的元语言，而C++托管扩展是在C++基础上建立起来的，用来为Visual C++程序员开发.NET框架应用程序而设计。为叙述方便，我们将C++托管扩展就称之为“托管C++”。<br />为了帮助C/C++以及Visual C++程序员或爱好者快速使用托管C++开发.NET Framework程序，我们将陆续推出相关的一系列文章。<br /><br />　　本篇“托管C++概述”主要讲述了什么是托管C++、开发.NET Framework(框架)的项目类型以及与标准C++之间的区别。<br /><br />　　<b><font color="#ac000">1、什么是托管C++？</font></b><br /><br />　　在回答这个问题，首先要搞清楚什么是“托管”(Managed)。托管是.NET的一个专门概念，它是融于通用语言运行时(CLR)中的一种新的编程理念，因此我们完全可以把“托管”视为“.NET”。那么什么是“通用语言运行时”？通用语言运行时是.NET 框架应用程序的执行引挚。它提供了许多服务，其中包括：代码管理(装入和执行)、类型安全性验证、元数据(高级类型信息)访问、为管理对象管理内存、管理代码，COM对象和预生成的DLLs(非管理代码和数据)的交互操作性、对开发人员服务的支持等等。<br /><br />　　也就是说，使用托管C++意味着，我们的代码可以被CLR所管理，并能开发出具有最新特性如垃圾自动收集、程序间相互访问等的.NET框架应用程序。<br /><br />　　由托管概念所引发的C++应用程序包括托管代码、托管数据和托管类三个组成部分。　　<br /><br />　　(1) <b>托管代码</b>：.Net环境提供了许多核心的运行(RUNTIME)服务，比如异常处理和安全策略。为了能使用这些服务，必须要给运行环境提供一些信息代码(元数据)，这种代码就是托管代码。所有的C#、VB.NET、JScript.NET默认时都是托管的，但Visual C++默认时不是托管的，必须在编译器中使用命令行选项(/CLR)才能产生托管代码。<br /><br />　　(2) <b>托管数据</b>：与托管代码密切相关的是托管数据。托管数据是由公共语言运行的垃圾回收器进行分配和释放的数据。默认情况下，C#、Visual Basic 和 JScript.NET 数据是托管数据。不过，通过使用特殊的关键字，C# 数据可以被标记为非托管数据。Visual C++数据在默认情况下是非托管数据，即使在使用 /CLR 开关时也不是托管的。<br /><br />　　(3)<b> 托管类</b>：尽管Visual C++数据在默认情况下是非托管数据，但是在使用C++的托管扩展时，可以使用“__gc”关键字将类标记为托管类。就像该名称所显示的那样，它表示类实例的内存由垃圾回收器管理。另外，一个托管类也完全可以成为 .NET 框架的成员，由此可以带来的好处是，它可以与其他语言编写的类正确地进行相互操作，如托管的C++类可以从Visual Basic类继承等。但同时也有一些限制，如托管类只能从一个基类继承等。需要说明的是，在托管C++应用程序中既可使用托管类也可以使用非托管类。这里的非托管类不是指标准C++类，而是使用托管C++语言中的__nogc关键字的类。<br /><br /><strong><font color="#ac0000">2、用托管C++可以开发.NET框架的项目类型<br /><br /></font></strong>　　使用托管C++应该是C++程序员编写.NET框架应用程序最好的一种选择，通过集成在Visual Studio.NET开发环境的托管C++向导，我们可以创建以下几种开发.NET框架的项目类型：<br /><br />　　(1) 托管C++应用程序:用来创建一个支持托管扩展的单独C++应用程序，使用它还可创建任何类型的应用程序，包括.NET框架客户应用程序。<br /><br />　　(2) 托管C++类库:用来创建一个支持托管扩展的C++DLL，使用它可以生成一个能被.NET框架应用程序调用的托管类型的组件。<br /><br />　　(3) 托管C++空项目：用来创建一个空的托管项目，该项目只含有支持托管扩展的正确编译和链接的开关选项。使用它能将一个已有的C++源文件进入到一个托管环境中。<br /><br />　　(4) 托管C++ Web服务：用于创建两个项目，一个是C++托管扩展项目，另一个是部署项目。<br /><br />　　<b><font color="#ac000">3、托管C++与标准C++的主要区别</font></b><br /><br />　　尽管托管C++是从标准C++建立而来的，但它与标准C++有着本质上的区别，这主要体现在以下几个方面：<br /><br />　　<b>(1) 广泛采用“名称空间”(namespace)</b><br /><br />　　名称空间是类型的一种逻辑命名方案，.NET使用该命名方案用于将类型按相关功能的逻辑类别进行分组，利用名称空间可以使开发人员更容易在代码中浏览和引用类型。当然，我们也可将名称空间理解成是一个“类库名”。 <br /><br />　　尽管很早Microsoft就在Visual C++中支持名称空间的编程方式，但是很少引起Visual C++程序员的普遍关注。现在在托管C++程序中，我们必须使用这一方式，即使用#using和using关键字。例如下面的简单程序代码是在控制台上输出“Hello World”：<br /><br /><table width="80%" bgcolor="#ffffff"><tbody><tr><td>#using <mscorlib.dll><br />using namespace System;<br />int main(void)<br />{<br />Console::WriteLine(S"Hello World");<br />return 0;<br />}</mscorlib.dll></td></tr></tbody></table><br />　　代码中，#using是用来将一个元数据文件输入到托管C++程序中，这些文件可以是包含托管数据和结构的MSIL (Microsoft intermediate language，微软中间语言)文件，如DLL、EXE、OBJ文件等。mscorlib.dll是.NET框架的一个核心类库，包含主要的名称空间System。程序的第二行代码“using namespace System;”用来使用System名称空间。System是.NET框架根名称空间，包含最基本的类型，如用于数据流的输入/输出的System::IO等。<br /><br />　　在对托管C++程序开发的不断深入，我们不久就会发现，许多类型的引用都要在程序的前面使用#using和using来进行。<br /><br />　　<b>(2) 基本数据类型的变化</b><br /><br />　　我们知道，标准C++语言的数据类型是非常丰富的。而托管C++的数据类型更加丰富，不仅包含了标准C++中的数据类型，而且新增了__int64(64位整型)、Decimal(96位十进制数)、String*(字符串类型)和Object*(对象类型)等类型，表1-1列出它们各自数据类型。<br /><br /><table cellspacing="0" width="80%" align="center" border="1"><tbody><tr><td width="139" height="19">类型描述</td><td width="203" height="19">标准C++类型名</td><td width="170" height="19">托管C++类型名</td><td width="70" height="19">长度(位)</td></tr><tr><td width="139">布尔型</td><td width="203">bool</td><td width="170">bool</td><td width="70">8</td></tr><tr><td width="139" height="19">字符型</td><td width="203" height="19">char</td><td width="170" height="19">signed char</td><td width="70" height="19">8</td></tr><tr><td width="139">无符号字符型</td><td width="203">unsigned char</td><td width="170">char</td><td width="70">8</td></tr><tr><td width="139">短整型</td><td width="203">short [int]</td><td width="170">short</td><td width="70">16</td></tr><tr><td width="139">无符号短整型</td><td width="203">unsigned short [int]</td><td width="170">unsigned short</td><td width="70">16</td></tr><tr><td width="139">整型</td><td width="203">int</td><td width="170">int 或 long</td><td width="70">32</td></tr><tr><td width="139">无符号整型</td><td width="203">unsigned [int]</td><td width="170">unsigned int 或 long</td><td width="70">32</td></tr><tr><td width="139">长整型</td><td width="203">long [int]</td><td width="170">long</td><td width="70">32</td></tr><tr><td width="139">无符号长整型</td><td width="203">unsigned long [int]</td><td width="170">unsigned long</td><td width="70">32</td></tr><tr><td width="139">单精度浮点型</td><td width="203">float</td><td width="170">float</td><td width="70">32</td></tr><tr><td width="139">双精度浮点型</td><td width="203">double</td><td width="170">double</td><td width="70">64</td></tr><tr><td width="139">长双精度浮点型</td><td width="203">long double</td><td width="170">--</td><td width="70">64</td></tr><tr><td width="139">Unicode字符</td><td width="203">--</td><td width="170">wchar_t</td><td width="70">16</td></tr><tr><td width="139">64位整型</td><td width="203">--</td><td width="170">__int64</td><td width="70">64</td></tr><tr><td width="139">无符号64位整型</td><td width="203">--</td><td width="170">unsigned __int64</td><td width="70">64</td></tr><tr><td width="139">96位十进制值</td><td width="203">--</td><td width="170">Decimal</td><td width="70">96</td></tr><tr><td width="139">对象类型</td><td width="203">--</td><td width="170">Object*</td><td width="70">32</td></tr><tr><td width="139">字符串类型</td><td width="203">--</td><td width="170">String*</td><td width="70">--</td></tr></tbody></table><br /><br />　　需要注意的是，String和Object在定义一个变量时，注意要有星号(“*”)，但这个变量不是指针变量，这与标准C++的含义是不一样的。例如上面的代码可以改为：<br /><br /><table width="80%" bgcolor="#ffffff"><tbody><tr><td>#using <mscorlib.dll><br />using namespace System;<br />int main(void)<br />{<br />String* hello = S"Hello World";<br />Console::WriteLine(hello);<br />return 0;<br />}</mscorlib.dll></td></tr></tbody></table>　<b>(3) 新增三个托管C++类型：__gc class、__value class和__gc interface</b><br /><br />　　一个__gc类或结构意味着该类或结构的生命周期是由.NET开发平台自动管理及垃圾自动收集，用户不必自已去调用delete来删除。定义一个__gc类或结构和标准C++基本相似，所不同的是在class或struct前加上__gc，例如下面的代码：<br /><br /><table width="80%" bgcolor="#ffffff"><tbody><tr><td>__gc class G {<br />public:<br />int k;<br />int sum(int);<br />};<br /><br />G::sum(int i) {return i*(i + 1)/2;}<br />int main()<br />{<br />G * g = new G;<br />Console::WriteLine(g-&gt;sum(4)); // 结果输出10<br />return 0;<br />}</td></tr></tbody></table><br />　　<b><font color="#ff0000">但要注意：</font></b><br /><br />　　A. 一个__gc类不能从一个非托管类中继承，且不能包含从它派生的非托管类。但一个__gc类最多可以从一个托管类中继承。<br /><br />　　B. 一个__gc类不能定义成一个友元类或包含一个友元成员函数。所谓友元函数，是用来让外部函数访问类中的私有和保护类型成员。<br /><br />　　C. 一个__gc类不能声明或定义以及重载new或delete操作以及不能包含using等声明。<br /><br />　　__value类是用来使用具有短生命期的小型数据项，它不同于__gc类。__gc类数据分配在CLR堆中，而__value类对象是在运行栈或称为NDP(.NET Developer Platform，.NET开发者平台)堆中创建的，从而避免了垃圾回收器不断分配和释放空间而带来的开销。一个__value类可以声明成为一个局部变量、参数和返回值，也可嵌入到一个__gc类中或是作为一个静态变量或在C++堆中分配的变量。例如下面的代码：<br /><br /><table width="80%" bgcolor="#ffffff"><tbody><tr><td>#using <mscorlib.dll><br />using namespace System;<br />__value struct V { int i; };<br />__gc struct G { V v; }; // 嵌入到__gc类中<br />V f(V v) { // 定义一个全局函数，其值存储在运行栈中<br />v.i += 1; // 不影响原来形参v的值<br />return v; // 返回V结构类型的值<br />}<br />int main(void) <br />{<br />V v1 = {10}; // 在运行栈中声明并初始化<br />V v2 = f(v1); // 调用f函数，此时v1中的i为10，而v2中的i为11<br />G *pG = new G; // 为G实例分配堆空间<br />pG-&gt;v = v1; // pG的v中的i为10<br />pG-&gt;v.i += v2.i; // pG的v中的i为10+11=21<br />Console::WriteLine(v1.i); // 输出结果为10<br />Console::WriteLine(v2.i); // 输出结果为11<br />Console::WriteLine(pG-&gt;v.i); // 输出结果为21<br />return 0;<br />}</mscorlib.dll></td></tr></tbody></table><br />　　除此之外，所有的__gc对象都是从类System::Object派生而来，因而能够很容易使用作用在__gc类中的集合和映射功能。然而__value类型并没有与这个基类所共享，因而不能直接将__value作为函数中的Object*实参。为了解决这个问题，.NET允许我们使用__box关键字将一个__value类型视为一个__gc对象。此时__value类型被封装成一个__gc类桩子(Stub)，并被复制到NDP堆中。由于在托管C++中，box不具备隐式转换的功能，因此在转换时必须指明转换的类型。<br /><br />　　托管C++中的__gc接口最能体现COM接口的思想，它的定义和声明是非常简单的，它除了关键字不同外，与一个__gc类的声明极为相似。例如下面的代码定义了一个接口IMyBase，其中包含了一个f的方法：<br /><br /><table width="80%" bgcolor="#ffffff"><tbody><tr><td>__gc __interface Ibase {<br />void f();<br />};</td></tr></tbody></table><br />　　需要说明的是，接口中所有的方法默认时都是纯虚的且都是公有的，我们不需要在方法之前使用virtual关键字或在方法之后加上“= 0”。其次，在一个__gc接口中不能包含数据成员以及静态成员，也不能包含任何类的声明。下面举一个示例来说明__gc接口的使用：<br /><br /><table width="80%" bgcolor="#ffffff"><tbody><tr><td>#using <mscorlib.dll><br />using namespace System;<br /><br />__gc __interface Ibase1 {<br />int f(int);<br />};<br />__gc __interface Ibase2 {<br />int f(int);<br />};<br />__gc struct C: Ibase1, Ibase2 {<br />int f(int i) { // 接口方法的实现<br />return 2*i-1;<br />};<br />};<br /><br />int main(void){<br />C* c = new C;<br />Console::WriteLine((c -&gt; f(1)).ToString()); // 输出结果为1<br />Console::WriteLine((__try_cast <ibase1 *="">(c)-&gt;f(2)).ToString()); <br />// 输出结果为3<br /><br />Console::WriteLine((__try_cast <ibase2 *="">(c)-&gt;f(3)).ToString());<br />// 输出结果为5<br /><br />return 0;<br />}</ibase2></ibase1></mscorlib.dll></td></tr></tbody></table><br />　　代码中，__try_cast用来将某个对象转换成一个指定类型，并当类型转换失败时自动处理由此产生的异常。ToString用来将对象描述成一个字符串。<br /><strong>(4) 简化属性操作<br /><br /></strong>　　在__gc类中可以使用.NET的属性，这个属性简化了属性函数的调用操作，这与标准C++中的属性不一样。在标准C++中分别通过get_和put_成员函数来设置或获取相关属性的值。现在，托管C++中的属性操作就好比是对一个属性变量进行操作，例如下列代码：<br /><br /><table width="80%" bgcolor="#ffffff"><tbody><tr><td>#using <mscorlib.dll><br />using namespace System;<br /><br />__gc class G {<br />public:<br />__property int get_Size() {<br />Console::WriteLine(S"get_属性");<br />return nSize;<br />};<br />__property void set_Size(int i) { <br />Console::WriteLine(S"set_属性");<br />nSize = i;<br />};<br />private:<br />int nSize;<br />};<br /><br />int main() {<br />G * pG = new G;<br />pG-&gt;Size = 10; // 调用set_Size<br />int i = pG-&gt;Size; // 调用get_Size<br />Console::WriteLine(i);<br />}</mscorlib.dll></td></tr></tbody></table><br />　　程序结果为：<br /><br />　　　set_属性<br /><br />　　　get_属性<br /><br />　　　10<br /><br />　　需要说明的是，托管C++使用__property关键字来定义一个属性的成员函数。从代码中可以看出设置和获取属性的成员函数名称中分别使用了set_和get_，这样编译器会自动生成一个伪成员变量Size，这个变量名是set_和get_成员函数后面的名称。注意不要再在get_成员函数代码中使用这个伪成员变量Size，它会引起该函数的递归调用。<br /><br />　　<b>(5) 托管C++的委派</b><br /><br />　　在C/C++中，一个函数的地址就是内存地址。这个地址不会带有任何其它附加信息，如函数的参数个数、参数类型、函数的返回值类型以及这个函数的调用规范等。总之，C/C++的回调函数不具备类型安全性。而.NET框架在回调函数的基础增加了提供类型安全的机制，称为委派。<br /><br />　　托管C++的委派方法不像C#那么复杂，它简化了委派绝大部分的内部机制，因而使得它的使用变成非常简单容易。例如下面的代码：<br /><br /><table width="80%" bgcolor="#ffffff"><tbody><tr><td>#using <mscorlib.dll><br />using namespace System;<br /><br />__delegate int GetDayOfWeek(); // 委派方法的声明<br />__gc class MyCalendar<br />{<br />public:<br />MyCalendar() : m_nDayOfWeek(4) {}<br />int MyGetDayOfWeek() {<br />Console::WriteLine("非静态方法"); <br />return m_nDayOfWeek; <br />}<br />static int MyStaticGetDayOfWeek() { <br />Console::WriteLine("静态方法"); <br />return 6; <br />}<br />private:<br />int m_nDayOfWeek;<br />};<br /><br />int main(void)<br />{<br />GetDayOfWeek * pGetDayOfWeek; // 声明委派类型变量<br />int nDayOfWeek;<br /><br />// 将类的静态方法MyStaticGetDayOfWeek绑定成委派<br />pGetDayOfWeek = new GetDayOfWeek(0, &amp;MyCalendar::MyStaticGetDayOfWeek);<br />nDayOfWeek = pGetDayOfWeek-&gt;Invoke(); // 委派的调用<br />Console::WriteLine(nDayOfWeek);<br /><br />// 将一个类的实例绑定成委派<br />MyCalendar * pcal = new MyCalendar();<br />pGetDayOfWeek = <br />static_cast<getdayofweek*>(Delegate::Combine(pGetDayOfWeek,<br />new GetDayOfWeek(pcal, &amp;MyCalendar::MyGetDayOfWeek)));<br />nDayOfWeek = pGetDayOfWeek-&gt;Invoke();<br />Console::WriteLine(nDayOfWeek);<br /><br />// 删除绑定委派的类实例<br />pGetDayOfWeek = <br />static_cast<getdayofweek*>(Delegate::Remove(pGetDayOfWeek,<br />new GetDayOfWeek(pcal, &amp;MyCalendar::MyGetDayOfWeek)));<br /><br />return 0;<br />}</getdayofweek*></getdayofweek*></mscorlib.dll></td></tr></tbody></table><br />　　输出结果是：<br /><br />　　　静态方法<br />　　<br />　　　6<br /><br />　　　静态方法<br /><br />　　　非静态方法<br /><br />　　　4<br /><br />　　<b><font color="#ac000">4、结速语</font></b><br /><br />　　总之，使用托管C++是C++程序员编写.NET框架应用程序最好的一种选择，在充分理解.NET框架基础上，避免了使用其他语言如C#、VB.NET所带来的额外开销。<br /><img src ="http://www.cppblog.com/mzty/aggbug/11393.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2006-08-18 10:18 <a href="http://www.cppblog.com/mzty/archive/2006/08/18/11393.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c++\CLI与c#</title><link>http://www.cppblog.com/mzty/archive/2006/08/17/11358.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Thu, 17 Aug 2006 08:46:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2006/08/17/11358.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/11358.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2006/08/17/11358.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/11358.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/11358.html</trackback:ping><description><![CDATA[
		<table class="data" width="80%" border="1">
				<tbody>
						<tr valign="top">
								<th class="data" align="left" width="25%">Description</th>
								<th class="data" align="left" width="37%">C++/CLI</th>
								<th class="data" align="left" width="38%">C#</th>
						</tr>
						<tr valign="top">
								<td class="data" width="25%">Allocate reference type</td>
								<td class="data" width="37%">
										<b>ReferenceType^ h = gcnew ReferenceType;</b>
								</td>
								<td class="data" width="38%">
										<b>ReferenceType h = new ReferenceType();</b>
								</td>
						</tr>
						<tr valign="top">
								<td class="data" width="25%">Allocate value type</td>
								<td class="data" width="37%">
										<b>ValueType v(3, 4);</b>
								</td>
								<td class="data" width="38%">
										<b>ValueType v = new ValueType(3, 4);</b>
								</td>
						</tr>
						<tr valign="top">
								<td class="data" width="25%">Reference type, stack semantics</td>
								<td class="data" width="37%">
										<b>ReferenceType h;</b>
								</td>
								<td class="data" width="38%">N/A</td>
						</tr>
						<tr valign="top">
								<td class="data" width="25%">Calling <b>Dispose</b> method</td>
								<td class="data" width="37%">
										<b>ReferenceType^ h = gcnew ReferenceType;</b>
										<p>
												<b>delete h;</b>
										</p>
								</td>
								<td class="data" width="38%">
										<b>ReferenceType h = new ReferenceType();</b>
										<p>
												<b>((IDisposable)h).Dispose();</b>
										</p>
								</td>
						</tr>
						<tr valign="top">
								<td class="data" width="25%">Implementing <b>Dispose</b> method</td>
								<td class="data" width="37%">
										<b>~TypeName() {}</b>
								</td>
								<td class="data" width="38%">
										<b>void IDisposable.Dispose() {}</b>
								</td>
						</tr>
						<tr valign="top">
								<td class="data" width="25%">Implementing <b>Finalize</b> method</td>
								<td class="data" width="37%">
										<b>!TypeName() {}</b>
								</td>
								<td class="data" width="38%">
										<b>~TypeName() {}</b>
								</td>
						</tr>
						<tr valign="top">
								<td class="data" width="25%">Boxing</td>
								<td class="data" width="37%">
										<b>int^ h = 123;</b>
								</td>
								<td class="data" width="38%">
										<b>object h = 123;</b>
								</td>
						</tr>
						<tr valign="top">
								<td class="data" width="25%">Unboxing</td>
								<td class="data" width="37%">
										<b>int^ hi = 123;</b>
										<p>
												<b>int c = *hi;</b>
										</p>
								</td>
								<td class="data" width="38%">
										<b>object h = 123;</b>
										<p>
												<b>int i = (int) h;</b>
										</p>
								</td>
						</tr>
						<tr valign="top">
								<td class="data" width="25%">Reference type definition</td>
								<td class="data" width="37%">
										<b>ref class ReferenceType {};</b>
										<p>
												<b>ref struct ReferenceType {};</b>
										</p>
								</td>
								<td class="data" width="38%">
										<b>class ReferenceType {}</b>
								</td>
						</tr>
						<tr valign="top">
								<td class="data" width="25%">Value type definition</td>
								<td class="data" width="37%">
										<b>value class ValueType {};</b>
										<p>
												<b>value struct ValueType {};</b>
										</p>
								</td>
								<td class="data" width="38%">
										<b>struct ValueType {}</b>
								</td>
						</tr>
						<tr valign="top">
								<td class="data" width="25%">Using properties</td>
								<td class="data" width="37%">
										<b>h.Prop = 123;</b>
										<p>
												<b>int v = h.Prop;</b>
										</p>
								</td>
								<td class="data" width="38%">
										<b>h.Prop = 123;</b>
										<p>
												<b>int v = h.Prop;</b>
										</p>
								</td>
						</tr>
						<tr valign="top">
								<td class="data" width="25%">Property definition</td>
								<td class="data" width="37%">
										<b>property String^ Name <br />{<br />    String^ get()<br />    {<br />        return m_value;<br />    }<br />    void set(String^ value)<br />    {<br />        m_value = value;<br />    }<br />}</b>
								</td>
								<td class="data" width="38%">
										<b>string Name <br />{<br />    get<br />    {<br />        return m_name;<br />    }<br />    set<br />    {<br />        m_name = value;<br />    }</b>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cppblog.com/mzty/aggbug/11358.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2006-08-17 16:46 <a href="http://www.cppblog.com/mzty/archive/2006/08/17/11358.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Native c++ 和Managed 的 interop</title><link>http://www.cppblog.com/mzty/archive/2006/08/17/11354.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Thu, 17 Aug 2006 08:26:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2006/08/17/11354.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/11354.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2006/08/17/11354.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/11354.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/11354.html</trackback:ping><description><![CDATA[
		<p>4种方法:<br /><br />There are four main ways to do interop in .NET between the managed and native worlds. COM interop can be accomplished using Runtime Callable Wrappers (RCW) and COM Callable Wrappers (CCW). The common language runtime (CLR) is responsible for type marshaling (except in the rare scenarios where a custom marshaler is used) and the cost of these calls can be expensive. You need to be careful that the interfaces are not too chatty; otherwise a large performance penalty could result. You also need to ensure that the wrappers are kept up to date with the underlying component. That said, COM interop is very useful for simple interop scenarios where you are attempting to bring in a large amount of native COM code.</p>
		<p>The second option for interop is to use P/Invoke. This is accomplished using the DllImport attribute, specifying the attribute on the method declaration for the function you want to import. Marshaling is handled according to how it has been specified in the declaration. However, DllImport is only useful if you have code that exposes the required functions through a DLL export.</p>
		<p>When you need to call managed code from native code, CLR hosting is an option. In such a scenario, the native application has to drive all of the execution: setting up the host, binding to the runtime, starting the host, retrieving the appropriate AppDomain, setting up the invocation context, locating the desired assembly and class, and invoking the operation on the desired class. This is definitely one of the most robust solutions in terms of control over what and when things happen, but it is also incredibly tedious and requires a lot of custom code.</p>
		<p>The fourth option, and quite possibly the easiest and the most performant, is to use the interop capabilities in C++. By throwing the /clr switch, the compiler generates MSIL instead of native machine code. The only code that is generated as native machine code is code that just can't be compiled to MSIL, including functions with inline asm blocks and operations that use CPU-specific intrinsics such as Streaming SIMD Extensions (SSE). The /clr switch is how the Quake II port to .NET was accomplished. The Vertigo software team spent a day porting the original C code for the game to code that successfully compiled as C++ and then threw the /clr switch. In no time they were up and running on the .NET Framework. Without adding any additional binaries and simply by including the appropriate header files, managed C++ and native C++ can call each other without any additional work on the part of the developer. The compiler handles the creation of the appropriate thunks to go back and forth between the two worlds.</p>
<img src ="http://www.cppblog.com/mzty/aggbug/11354.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2006-08-17 16:26 <a href="http://www.cppblog.com/mzty/archive/2006/08/17/11354.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Visual C++ 编译器选项</title><link>http://www.cppblog.com/mzty/archive/2006/08/17/11336.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Thu, 17 Aug 2006 04:16:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2006/08/17/11336.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/11336.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2006/08/17/11336.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/11336.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/11336.html</trackback:ping><description><![CDATA[
		<p class="label">
				<b>来自msdn:http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/vccore/html/_core_compiler_options_listed_by_category.asp<br /><br />优化</b>
		</p>
		<div class="tablediv">
				<table class="dtTABLE" cellspacing="0" width="80%" border="1">
						<tbody>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.o1.2c_2f.o2.asp">/O1</a>
										</td>
										<td width="71%">创建小代码</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.o1.2c_2f.o2.asp">/O2</a>
										</td>
										<td width="71%">创建快速代码</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.oa.2c_2f.ow.asp">/Oa</a>
										</td>
										<td width="71%">假设没有别名</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.ob.asp">/Ob</a>
										</td>
										<td width="71%">控制内联展开</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.od.asp">/Od</a>
										</td>
										<td width="71%">禁用优化</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.og.asp">/Og</a>
										</td>
										<td width="71%">使用全局优化</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.oi.asp">/Oi</a>
										</td>
										<td width="71%">生成内部函数</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.op.asp">/Op</a>
										</td>
										<td width="71%">改善浮点数一致性</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.os.asp">/Os</a>
										</td>
										<td width="71%">代码大小优先</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.os.asp">/Ot</a>
										</td>
										<td width="71%">代码速度优先</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.oa.2c_2f.ow.asp">/Ow</a>
										</td>
										<td width="71%">假定在函数调用中使用别名</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.ox.asp">/Ox</a>
										</td>
										<td width="71%">使用最大优化 (/Ob2gity /Gs)</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.oy.asp">/Oy</a>
										</td>
										<td width="71%">省略框架指针</td>
								</tr>
						</tbody>
				</table>
		</div>
		<p class="label">
				<b>代码生成</b>
		</p>
		<div class="tablediv">
				<table class="dtTABLE" cellspacing="0" width="80%" border="1">
						<tbody>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vclrfarchminimumcpuarchitecture.asp">/arch</a>
										</td>
										<td width="71%">使用 SSE 或 SSE2 指令生成代码</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vcrefeecomcompilation.asp">/clr</a>
										</td>
										<td width="71%">启用 C++ 的托管扩展并产生在公共语言运行库上运行的输出文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.eh.asp">/EH</a>
										</td>
										<td width="71%">指定异常处理模型</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.g.asp">/G3</a>
										</td>
										<td width="71%">优化代码以优选 386 处理器。在 Visual C++ 5.0 中已经停用，编译器将忽略此选项</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.g.asp">/G4</a>
										</td>
										<td width="71%">优化代码以优选 486 处理器。在 Visual C++ 5.0 中已经停用，编译器将忽略此选项</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.g.asp">/G5</a>
										</td>
										<td width="71%">优化代码以优选 Pentium</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.g.asp">/G6</a>
										</td>
										<td width="71%">优化代码以优选 Pentium Pro、Pentium II 和 Pentium III 处理器</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.g.asp">/G7</a>
										</td>
										<td width="71%">针对 Pentium 4 或 Athlon 优化代码。</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.g.asp">/GB</a>
										</td>
										<td width="71%">与 /G6 等效；将 _M_IX86 的值设置为 600</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.gd.2c_2f.gr.2c_2f.gz.asp">/Gd</a>
										</td>
										<td width="71%">使用 <b>__cdecl</b> 调用约定</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.ge.asp">/Ge</a>
										</td>
										<td width="71%">激活堆栈探测</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.gf.asp">/GF</a>
												<br />
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.gf.asp">/Gf</a>
										</td>
										<td width="71%">启用字符串池</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.gh.asp">/Gh</a>
										</td>
										<td width="71%">调用挂钩函数 <b>_penter</b></td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vcrefghenable__pexithookfunction.asp">/GH</a>
										</td>
										<td width="71%">调用挂钩函数 <b>_pexit</b></td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vcgrfglwholeprogramoptimization.asp">/GL</a>
										</td>
										<td width="71%">启用全程序优化</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.gm_minimal.asp">/Gm</a>
										</td>
										<td width="71%">启用最小重新生成</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.gr_option.asp">/GR</a>
										</td>
										<td width="71%">启用运行时类型信息 (RTTI)</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.gd.2c_2f.gr.2c_2f.gz.asp">/Gr</a>
										</td>
										<td width="71%">使用 <b>__fastcall</b> 调用约定</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.gs.asp">/Gs</a>
										</td>
										<td width="71%">控制堆栈探测</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.gt.asp">/GT</a>
										</td>
										<td width="71%">支持使用静态线程本地存储区分配的数据的纤程安全</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.gx.asp">/GX</a>
										</td>
										<td width="71%">启用同步异常处理</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.gy.asp">/Gy</a>
										</td>
										<td width="71%">启用函数级链接</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.gd.2c_2f.gr.2c_2f.gz.asp">/Gz</a>
										</td>
										<td width="71%">使用 <b>__stdcall</b> 调用约定</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.md.2c_2f.ml.2c_2f.mt.2c_2f.ld.asp">/MD</a>
										</td>
										<td width="71%">使用 MSVCRT.lib 创建多线程 DLL</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.md.2c_2f.ml.2c_2f.mt.2c_2f.ld.asp">/MDd</a>
										</td>
										<td width="71%">使用 MSVCRTD.lib 创建调试多线程 DLL</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.md.2c_2f.ml.2c_2f.mt.2c_2f.ld.asp">/ML</a>
										</td>
										<td width="71%">使用 LIBC.lib 创建单线程可执行文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.md.2c_2f.ml.2c_2f.mt.2c_2f.ld.asp">/MLd</a>
										</td>
										<td width="71%">使用 LIBCD.lib 创建调试单线程可执行文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.md.2c_2f.ml.2c_2f.mt.2c_2f.ld.asp">/MT</a>
										</td>
										<td width="71%">使用 LIBCMT.lib 创建多线程可执行文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.md.2c_2f.ml.2c_2f.mt.2c_2f.ld.asp">/MTd</a>
										</td>
										<td width="71%">使用 LIBCMTD.lib 创建调试多线程可执行文件</td>
								</tr>
						</tbody>
				</table>
		</div>
		<p class="label">
				<b>输出文件</b>
		</p>
		<div class="tablediv">
				<table class="dtTABLE" cellspacing="0" width="80%" border="1">
						<tbody>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.fa.asp">/FA</a>
												<br />
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.fa.asp">/Fa</a>
										</td>
										<td width="71%">创建列表文件<br />设置列表文件名</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.fd.asp">/Fd</a>
										</td>
										<td width="71%">重命名程序数据库文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.fe.asp">/Fe</a>
										</td>
										<td width="71%">重命名可执行文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.fm.asp">/Fm</a>
										</td>
										<td width="71%">创建映射文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.fo.asp">/Fo</a>
										</td>
										<td width="71%">创建对象文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.fp.asp">/Fp</a>
										</td>
										<td width="71%">指定预编译头文件名</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.fr.2c_2f.fr.asp">/FR</a>
												<br />
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.fr.2c_2f.fr.asp">/FR</a>
										</td>
										<td width="71%">生成浏览器文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vcrefFxMergeInjectedCode.asp">/Fx</a>
										</td>
										<td width="71%">将插入的代码与源文件合并</td>
								</tr>
						</tbody>
				</table>
		</div>
		<p class="label">
				<b>调试</b>
		</p>
		<div class="tablediv">
				<table class="dtTABLE" cellspacing="0" width="80%" border="1">
						<tbody>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vclrfgsbuffersecurity.asp">/GS</a>
										</td>
										<td width="71%">缓冲区安全检查</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vcrefgz(catchrelease-builderrorsindebugbuild).asp">/GZ</a>
										</td>
										<td width="71%">与 <a href="http://msdn.microsoft.com/library/CHS/vccore/html/vcrefrtcruntimechecks.asp">/RTC1</a> 相同</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vcrefrtcruntimechecks.asp">/RTC</a>
										</td>
										<td width="71%">启用运行时错误检查</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vchowwp64detect64bitportabilityproblems.asp">/Wp64</a>
										</td>
										<td width="71%">检测 64 位可移植性问题</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.yd.asp">/Yd</a>
										</td>
										<td width="71%">将完整的调试信息放在所有对象文件中</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vcrefylinjectpchreferencefordebuglib.asp">/Yl</a>
										</td>
										<td width="71%">创建调试库时插入 PCH 引用</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.z7.2c_2f.zd.2c_2f.zi.asp">/Z7</a>
										</td>
										<td width="71%">生成与 C 7.0 兼容的调试信息</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.z7.2c_2f.zd.2c_2f.zi.asp">/Zd</a>
										</td>
										<td width="71%">生成行号</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.z7.2c_2f.zd.2c_2f.zi.asp">/Zi</a>
										</td>
										<td width="71%">生成完整的调试信息</td>
								</tr>
						</tbody>
				</table>
		</div>
		<p class="label">
				<b>预处理器</b>
		</p>
		<div class="tablediv">
				<table class="dtTABLE" cellspacing="0" width="80%" border="1">
						<tbody>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vclrfaispecifymetadatadirectories.asp">/AI</a>
										</td>
										<td width="71%">指定在解析传递到 #using 指令的文件引用时搜索的目录</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.c_uc.asp">/C</a>
										</td>
										<td width="71%">在预处理期间保留注释</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.d.asp">/D</a>
										</td>
										<td width="71%">定义常数和宏</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.e.asp">/E</a>
										</td>
										<td width="71%">将预处理器输出复制到标准输出</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.ep.asp">/EP</a>
										</td>
										<td width="71%">将预处理器输出复制到标准输出</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.fi.asp">/Fl</a>
										</td>
										<td width="71%">预处理指定的包含文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vclrffunameforcedusingfile.asp">/FU</a>
										</td>
										<td width="71%">强制使用文件名，就像它已被传递到 #using 指令一样</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.i.asp">/I</a>
										</td>
										<td width="71%">在目录中搜索包含文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.p.asp">/P</a>
										</td>
										<td width="71%">将预处理器输出写入文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.u.2c_2f.u.asp">/U</a>
										</td>
										<td width="71%">移除预定义宏</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.u.2c_2f.u.asp">/u</a>
										</td>
										<td width="71%">移除所有的预定义宏</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.x.asp">/X</a>
										</td>
										<td width="71%">忽略标准包含目录</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a class="POPUP" href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.z7.2c_2f.zd.2c_2f.zi.asp">/ZI</a>
										</td>
										<td width="71%">将调试信息包含在与“编辑并继续”兼容的程序数据库中</td>
								</tr>
						</tbody>
				</table>
		</div>
		<p class="label">
				<b>语言</b>
		</p>
		<div class="tablediv">
				<table class="dtTABLE" cellspacing="0" width="80%" border="1">
						<tbody>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.vd.asp">/vd</a>
										</td>
										<td width="71%">取消或启用隐藏的 vtordisp 类成员</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.vmb.2c_2f.vmg.asp">/vmb</a>
										</td>
										<td width="71%">对指向成员的指针使用最佳的基</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.vmb.2c_2f.vmg.asp">/vmg</a>
										</td>
										<td width="71%">对指向成员的指针使用完全一般性</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.vmm.2c_2f.vms.2c_2f.vmv.asp">/vmm</a>
										</td>
										<td width="71%">声明多重继承</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.vmm.2c_2f.vms.2c_2f.vmv.asp">/vms</a>
										</td>
										<td width="71%">声明单一继承</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.vmm.2c_2f.vms.2c_2f.vmv.asp">/vmv</a>
										</td>
										<td width="71%">声明虚拟继承</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.za.2c_2f.ze.asp">/Za</a>
										</td>
										<td width="71%">禁用语言扩展</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vcrefzcconformance.asp">/Zc</a>
										</td>
										<td width="71%">在 <a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.za.2c_2f.ze.asp">/Ze</a> 下指定标准行为</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.za.2c_2f.ze.asp">/Ze</a>
										</td>
										<td width="71%">启用语言扩展</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.zg.asp">/Zg</a>
										</td>
										<td width="71%">生成函数原型</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.zl.asp">/Zl</a>
										</td>
										<td width="71%">从 .obj 文件中移除默认库名</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.zp.asp">/Zp</a>
												<i>n</i>
										</td>
										<td width="71%">封装结构成员</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.zs.asp">/Zs</a>
										</td>
										<td width="71%">只检查语法</td>
								</tr>
						</tbody>
				</table>
		</div>
		<p class="label">
				<b>链接</b>
		</p>
		<div class="tablediv">
				<table class="dtTABLE" cellspacing="0" width="80%" border="1">
						<tbody>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.f.asp">/F</a>
										</td>
										<td width="71%">设置堆栈大小</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.md.2c_2f.ml.2c_2f.mt.2c_2f.ld.asp">/LD</a>
										</td>
										<td width="71%">创建动态链接库</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.md.2c_2f.ml.2c_2f.mt.2c_2f.ld.asp">/LDd</a>
										</td>
										<td width="71%">创建调试动态链接库</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.link.asp">/link</a>
										</td>
										<td width="71%">将指定的选项传递给 LINK</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.md.2c_2f.ml.2c_2f.mt.2c_2f.ld.asp">/MD</a>
										</td>
										<td width="71%">使用 MSVCRT.lib 编译以创建多线程 DLL</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.md.2c_2f.ml.2c_2f.mt.2c_2f.ld.asp">/MDd</a>
										</td>
										<td width="71%">使用 MSVCRTD.lib 编译以创建调试多线程 DLL</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.md.2c_2f.ml.2c_2f.mt.2c_2f.ld.asp">/ML</a>
										</td>
										<td width="71%">使用 LIBC.lib 编译以创建单线程可执行文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.md.2c_2f.ml.2c_2f.mt.2c_2f.ld.asp">/MLd</a>
										</td>
										<td width="71%">使用 LIBCD.lib 编译以创建调试单线程可执行文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.md.2c_2f.ml.2c_2f.mt.2c_2f.ld.asp">/MT</a>
										</td>
										<td width="71%">使用 LIBCMT.lib 编译以创建多线程可执行文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.md.2c_2f.ml.2c_2f.mt.2c_2f.ld.asp">/MTd</a>
										</td>
										<td width="71%">使用 LIBCMTD.lib 编译以创建调试多线程可执行文件</td>
								</tr>
						</tbody>
				</table>
		</div>
		<p class="label">
				<b>预编译头</b>
		</p>
		<div class="tablediv">
				<table class="dtTABLE" cellspacing="0" width="80%" border="1">
						<tbody>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vclrfyignoreprecompiledheaderoptions.asp">/Y-</a>
										</td>
										<td width="71%">忽略当前生成中的所有其他预编译头编译器选项</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.yc.asp">/Yc</a>
										</td>
										<td width="71%">创建预编译头文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.yd.asp">/Yd</a>
										</td>
										<td width="71%">将完整的调试信息放在所有对象文件中</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.yu.asp">/Yu</a>
										</td>
										<td width="71%">在生成期间使用预编译头文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.yx.asp">/YX</a>
										</td>
										<td width="71%">自动处理预编译头</td>
								</tr>
						</tbody>
				</table>
		</div>
		<p class="label">
				<b>杂项</b>
		</p>
		<div class="tablediv">
				<table class="dtTABLE" cellspacing="0" width="80%" border="1">
						<tbody>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vctbsspecifyresponsefile.asp">@</a>
										</td>
										<td width="71%">指定响应文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.help.asp">/?</a>
										</td>
										<td width="71%">列出编译器选项</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.c_lc.asp">/c</a>
										</td>
										<td width="71%">编译但不链接</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.h.asp">/H</a>
										</td>
										<td width="71%">限制外部（公共）名称的长度</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.help.asp">/HELP</a>
										</td>
										<td width="71%">列出编译器选项</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.j.asp">/J</a>
										</td>
										<td width="71%">更改默认的 <b>char</b> 类型</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vclrfnologosuppressdisplayofbanner.asp">/nologo</a>
										</td>
										<td width="71%">取消显示登录版权标志</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.qi0f.asp">/QI0f</a>
										</td>
										<td width="71%">确保 Pentium 0F 指令没有问题</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.qifdiv.asp">/QIfdiv</a>
										</td>
										<td width="71%">FDIV、FPREM、FPTAN 和 FPATAN 指令有缺陷的 Intel Pentium 微处理器的变通方法</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vcrefqifistsuppress_ftol.asp">QIfist</a>
										</td>
										<td width="71%">当需要从浮点类型转换为整型时取消 Helper 函数 <b>_ftol</b> 的调用</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vcrefshowincludes.asp">/showIncludes</a>
										</td>
										<td width="71%">在编译期间显示所有包含文件的列表</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.tc.2c_2f.tp.asp">/Tc</a>
												<br />
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.tc.2c_2f.tp.asp">/TC</a>
										</td>
										<td width="71%">指定 C 源文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.tc.2c_2f.tp.asp">/Tp</a>
												<br />
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.tc.2c_2f.tp.asp">/TP</a>
										</td>
										<td width="71%">指定 C++ 源文件</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.v.asp">/V</a>
										</td>
										<td width="71%">设置版本字符串</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.w.2c_2f.w.asp">/W</a>
										</td>
										<td width="71%">设置警告等级</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.w.2c_2f.w.asp">/w</a>
										</td>
										<td width="71%">禁用所有警告</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.w.2c_2f.w.asp">/Wall</a>
										</td>
										<td width="71%">启用所有警告，包括默认情况下禁用的警告</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/vcrefwlenableonelinediagnostics.asp">/WL</a>
										</td>
										<td width="71%">在从命令行编译 C++ 源代码时启用错误信息和警告消息的单行诊断</td>
								</tr>
								<tr valign="top">
										<td width="29%">
												<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_.2f.zm.asp">/Zm</a>
										</td>
										<td width="71%">指定预编译头内存分配限制</td>
								</tr>
						</tbody>
				</table>
		</div>
		<h4 class="dtH4">请参见</h4>
		<p>
				<a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_overviews.3a_.compiling_and_linking.asp">C/C++ 生成参考</a> | <a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_compiler_reference.asp">编译器选项</a> | <a href="http://msdn.microsoft.com/library/CHS/vccore/html/_core_set_compiler_options.asp">设置编译器选项</a></p>
<img src ="http://www.cppblog.com/mzty/aggbug/11336.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2006-08-17 12:16 <a href="http://www.cppblog.com/mzty/archive/2006/08/17/11336.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>非托管的vc工程中部分文件使用.Net Framwork</title><link>http://www.cppblog.com/mzty/archive/2006/08/17/11334.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Thu, 17 Aug 2006 04:05:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2006/08/17/11334.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/11334.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2006/08/17/11334.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/11334.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/11334.html</trackback:ping><description><![CDATA[<font style="BACKGROUND-COLOR: #ff1493">使用vs2005环</font> <font style="BACKGROUND-COLOR: #ff1493">境 ,且工程不使用与编译头文件stdafx.h.(保证可以,不可以来找我!)</font> <br><br>一,建立一般的c++的console32的project ,name: Test ,工程setting使用默认,不改变.如下:<br><img style="WIDTH: 571px; HEIGHT: 398px" height=398 alt=r_testclass.jpg src="http://www.cppblog.com/images/cppblog_com/mzty/2021/r_testclass.jpg" width=571 border=0><br>二,add header file: ManagedCppClass.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;&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">class</span><span style="COLOR: #000000">&nbsp;ManagedCppClass<br><img id=Codehighlighter1_37_70_Open_Image onclick="this.style.display='none'; Codehighlighter1_37_70_Open_Text.style.display='none'; Codehighlighter1_37_70_Closed_Image.style.display='inline'; Codehighlighter1_37_70_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_37_70_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_37_70_Closed_Text.style.display='none'; Codehighlighter1_37_70_Open_Image.style.display='inline'; Codehighlighter1_37_70_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_37_70_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_37_70_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;PrintString();<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/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;</span></div>
<br>三,add cpp file: ManagedCppClass.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">#</span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">mscorlib.dll</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;<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><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">ManagedCppClass.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">void</span><span style="COLOR: #000000">&nbsp;ManagedCppClass::PrintString()<br><img id=Codehighlighter1_114_174_Open_Image onclick="this.style.display='none'; Codehighlighter1_114_174_Open_Text.style.display='none'; Codehighlighter1_114_174_Closed_Image.style.display='inline'; Codehighlighter1_114_174_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_114_174_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_114_174_Closed_Text.style.display='none'; Codehighlighter1_114_174_Open_Image.style.display='inline'; Codehighlighter1_114_174_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_114_174_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_114_174_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Console::WriteLine(S</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello,&nbsp;i&nbsp;am&nbsp;a&nbsp;Managed&nbsp;cpp&nbsp;class&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
四 main函数如下:<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">ManagedCppClass.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">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_87_144_Open_Image onclick="this.style.display='none'; Codehighlighter1_87_144_Open_Text.style.display='none'; Codehighlighter1_87_144_Closed_Image.style.display='inline'; Codehighlighter1_87_144_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_87_144_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_87_144_Closed_Text.style.display='none'; Codehighlighter1_87_144_Open_Image.style.display='inline'; Codehighlighter1_87_144_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_87_144_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_87_144_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;ManagedCppClass&nbsp;test;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;test.PrintString();<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>
五,修改Managedcppclass.cpp文件的property setting,<br><img style="WIDTH: 589px; HEIGHT: 412px" height=412 alt=r_managedcppclass.jpg src="http://www.cppblog.com/images/cppblog_com/mzty/2021/r_managedcppclass.jpg" width=589 border=0><br>next<br><img style="WIDTH: 587px; HEIGHT: 408px" height=408 alt=o_managedcppclass2.jpg src="http://www.cppblog.com/images/cppblog_com/mzty/2021/o_managedcppclass2.jpg" width=587 border=0><br>六,compile-&gt;link-&gt;run ,it is ok!<img src ="http://www.cppblog.com/mzty/aggbug/11334.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2006-08-17 12:05 <a href="http://www.cppblog.com/mzty/archive/2006/08/17/11334.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用c++\CLI实现c++托管与非托管混合编程</title><link>http://www.cppblog.com/mzty/archive/2006/08/16/11288.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Wed, 16 Aug 2006 06:23:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2006/08/16/11288.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/11288.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2006/08/16/11288.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/11288.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/11288.html</trackback:ping><description><![CDATA[
		<h2>Mixing Native and Managed Types in C++ </h2>
		<p>Wow, its turning into a busy month. I just haven’t had any time to blog despite having a number of interesting topics to cover. I’ll try to get a few of them written soon. Here’s a topic from one of my regular readers. </p>
		<p>The CLR naturally supports mixing managed and native method calls allowing you to easily call native functions from managed functions (which are of course natively compiled before execution) and visa versa. This is all largely transparent in C++. What’s not as transparent is how to mix managed and native <strong>types</strong>. The reason is that there is a greater distinction between native and managed types compared with function calls. Beside obvious differences such as those introduced by different calling conventions and virtual invocation, function calls aren’t all that different. Types however require a bit more help from the programmer/compiler since native and managed types can have very different characteristics. This is very evident in C# as you often need to decorate native type definitions with all kinds of attributes to control memory layout and marshalling. Fortunately for the C++ programmer the compiler takes care of much of this when you define or include native type definitions such as those found in the various Windows header files, but the programmer is still responsible for telling the compiler just how those types are to be used. </p>
		<p>Visual C++ provides many of the building blocks for mixing native and managed types but in some cases you need to write a little code to help it along. Fortunately C++/CLI is very capable. Let’s consider a few different scenarios. </p>
		<p>
				<strong>Embed Simple Managed Type in Native Type</strong>
		</p>
		<p>Since the CLR needs to keep track of every single instance of a managed type in a process, storing some kind of reference/pointer/handle to a managed object in a native type is not directly supported since instances of native types can be allocated in any region of memory and cast to all kinds of foreign data types that would be completely opaque to the CLR and its services. Instead you need to register such occurrences with the CLR so that it is aware of these “native” references to managed types. This is achieved with the use of the <strong>GCHandle</strong> type. Internally GCHandle manages a static table of (native) pointers that are used to lookup the objects in the managed heap. Of course using GCHandle directly from C++ can be quite tedious. It’s a CLS compliant value type which means native pointers are represented by <strong>IntPtr</strong> values. It also does not preserve static type information so <strong>static_cast</strong>s are inevitable. Fortunately Visual C++ ships with the <strong>gcroot</strong> native template class that provides a strongly-typed interface over the GCHandle type. </p>
		<p>
				<font face="Courier New">#include &lt;vcclr.h&gt;<br /> <br />ref struct ManagedType<br />{<br />    void HelloDotNet()<br />    {<br />        Console::WriteLine("Hello .NET");<br />    }<br />};<br /> <br />struct NativeType<br />{<br />    ManagedType m1;          // Error! <br />    <br />    ManagedType^ m2;         // Error!<br />    <br />    gcroot&lt;ManagedType^&gt; m3; // OK<br />};<br /> <br />void main()<br />{<br />    NativeType native;<br />    native.m3 = gcnew ManagedType;<br /> <br />    native.m3-&gt;HelloDotNet();<br />}</font>
		</p>
		<p>As you can see, gcroot provides a “smart” pointer for storing handles in native types. It may be smart but it does not provide automatic cleanup of resources. Specifically, the gcroot destructor makes no attempt to dispose of the managed object’s resources.</p>
		<p>
				<strong>Embed Managed Resource in Native Type</strong>
		</p>
		<p>Enter the <strong>auto_gcroot</strong> class. This native template class wraps a gcroot and provides <strong>transfer-of-ownership</strong> semantics for managed objects stored in native types. If you’re looking for a point of reference, think of the <strong>auto_ptr</strong> template class from the Standard C++ Library which does the same thing for native pointers. The auto_gcroot destructor takes care of “deleting” the handle which results in the object’s IDisposable::Dispose method (if any) being called.</p>
		<p>
				<font face="Courier New">#include &lt;msclr\auto_gcroot.h&gt;<br /> <br />ref struct ManagedType<br />{<br />    void HelloDotNet()<br />    {<br />        Console::WriteLine("Hello .NET");<br />    }<br /> <br />    ~ManagedType()<br />    {<br />        Console::WriteLine("dtor");</font>
		</p>
		<p>
				<font face="Courier New">        // Compiler implements Dispose pattern...<br />    }<br />};<br /> <br />struct NativeType<br />{<br />    msclr::auto_gcroot&lt;ManagedType^&gt; m3; // OK<br />};<br /> <br />void main()<br />{<br />    NativeType native;<br />    native.m3 = gcnew ManagedType;<br /> <br />    native.m3-&gt;HelloDotNet();<br />}</font>
		</p>
		<p>The NativeType destructor (provided by the compiler) will automatically call the auto_gcroot destructor which will delete the managed object resulting in its destructor being called through its compiler generated Dispose method.</p>
		<p>
				<strong>Embed Native Type in Managed Type</strong>
		</p>
		<p>Now let’s turn things around. Let’s say we want to store a native type as a member of a managed type. The challenge is that the only native type the CLR really supports within managed types is a native pointer. C# programmers use IntPtr but that is only because IntPtr is the CLS compliant way of representing a native pointer and C# tries really hard to remain CLS compliant. The CLR fully supports storing native pointers without losing type information. </p>
		<p>
				<font face="Courier New">struct NativeType<br />{<br />};<br /> <br />ref struct ManagedType<br />{<br />    NativeType n1; // Error!</font>
		</p>
		<p>
				<font face="Courier New">    NativeType* n2; // OK<br />};</font>
		</p>
		<p>That’s great except that now we have a resource management issue. Recall that C++ does not have the separation of memory and resource management evident in the CLR. The native object pointed to by the ManagedType member needs to be deleted. Here is one solution.</p>
		<p>
				<font face="Courier New">ref struct ManagedType<br />{<br />    NativeType* n2; // OK<br /> <br />    ~ManagedType()<br />    {<br />        if (0 != n2)<br />        {<br />            delete n2;<br />            n2 = 0;<br />        }<br />    }<br />};</font>
		</p>
		<p>Now the ManagedType has a Dispose implementation that will faithfully delete the native object. But this can become tedious and error prone very quickly. A better solution is to use some kind of “automatic” approach. Fortunately C++/CLI support <strong>by-value </strong>semantics for members so all we need is a managed auto-pointer template class. With such a class the ManagedType becomes really simple.</p>
		<p>
				<font face="Courier New">ref struct ManagedType<br />{<br />    AutoPtr&lt;NativeType&gt; n2; // OK<br />};</font>
		</p>
		<p>ManagedType stores a pointer to a native object and its destructor automatically deletes the object. Woohoo!</p>
		<p>The C++ compiler really takes care of a lot of boilerplate code. If you’re not sure just how much code the compiler is taking care of for you then take a look at the compiled assembly in a disassembler.</p>
		<p>Although Visual C++ does not provide a managed AutoPtr class, it is reasonably simple to write one. Here is a basic implementation.</p>
		<p>
				<font face="Courier New">template &lt;typename T&gt;<br />ref struct AutoPtr<br />{<br />    AutoPtr() : m_ptr(0)<br />    {<br />        // Do nothing<br />    }<br />    AutoPtr(T* ptr) : m_ptr(ptr)<br />    {<br />        // Do nothing<br />    }<br />    AutoPtr(AutoPtr&lt;T&gt;% right) : m_ptr(right.Release())<br />    {<br />        // Do nothing<br />    }<br />    ~AutoPtr()<br />    {<br />        if (0 != m_ptr)<br />        {<br />            delete m_ptr;<br />            m_ptr = 0;<br />        }<br />    }<br />    T&amp; operator*()<br />    {<br />        return *m_ptr;<br />    }<br />    T* operator-&gt;()<br />    {<br />        return m_ptr;<br />    }<br />    T* Get()<br />    {<br />        return m_ptr;<br />    }<br />    T* Release()<br />    {<br />        T* released = m_ptr;<br />        m_ptr = 0;<br />        return released;<br />    }<br />    void Reset()<br />    {<br />        Reset(0);<br />    }<br />    void Reset(T* ptr)<br />    {<br />        if (0 != m_ptr)<br />        {<br />            delete m_ptr;<br />        }<br />        m_ptr = ptr;<br />    }<br />private:<br />    T* m_ptr;<br />};</font>
		</p>
		<p>In a future post I may provide a few realistic examples of mixing native and managed code, but I hope this introduction has given you a few ideas on how to mix native and managed code and types effectively in C++.<br /><br /><br />来自: http://weblogs.asp.net/kennykerr/archive/2005/07/12/Mixing-Native-and-Managed-Types-in-C_2B002B00_.aspx<br /><br /></p>
<img src ="http://www.cppblog.com/mzty/aggbug/11288.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2006-08-16 14:23 <a href="http://www.cppblog.com/mzty/archive/2006/08/16/11288.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>A first look at C++/CLI(C++的管理扩展)</title><link>http://www.cppblog.com/mzty/archive/2005/12/29/2240.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Thu, 29 Dec 2005 07:14:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2005/12/29/2240.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/2240.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2005/12/29/2240.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/2240.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/2240.html</trackback:ping><description><![CDATA[
		<h2>Introduction</h2>
		<p>When Microsoft brought out the Managed Extensions to C++ with VS.NET 7, C++ programmers accepted it with mixed reactions. While most people were happy that they could continue using C++, nearly everyone was unhappy with the ugly and twisted syntax offered by Managed C++. Microsoft obviously took the feedback it got very seriously and they decided that the MC++ syntax wasn't going to be much of a success. </p>
		<p>On October 6th 2003, the ECMA <a href="http://www.ecma-international.org/news/ecma-TG5-PR.htm" target="_blank">announced</a> the creation of a new task group to oversee development of a standard set of language extensions to create a binding between the ISO standard C++ programming language and Common Language Infrastructure (CLI). It was also made known that this new set of language extensions will be known as the C++/CLI standard, which will be supported by the VC++ compiler starting with the Whidbey release (VS.NET 2005). </p>
		<h2>Problems with the old syntax</h2>
		<ul>
				<li>Ugly and twisted syntax and grammar - All those double underscores weren't exactly pleasing to the eye. 
</li>
				<li>Second class CLI support - Compared to C# and VB.NET, MC++ used contorted workarounds to provide CLI support, for e.g. it didn't have a for-each construct to enumerate .NET collections. 
</li>
				<li>Poor integration of C++ and .NET - You couldn’t use C++ features like templates on CLI types and you couldn’t use CLI features like garbage collection on C++ types. 
</li>
				<li>Confusing pointer usage - Both unmanaged C++ pointers and managed reference pointers used the same <code lang="mc++">*</code> based syntax which was quite confusing because <code lang="mc++"><span class="cpp-keyword">__gc</span></code> pointers were totally different in nature and behavior from unmanaged pointers. 
</li>
				<li>The MC++ compiler could not produce verifiable code </li>
		</ul>
		<h2>What C++/CLI gives us?</h2>
		<ul>
				<li>Elegant syntax and grammar -This gave a natural feel for C++ developers writing managed code and allowed a smooth transition from unmanaged coding to managed coding. All those ugly double underscores are gone now. 
</li>
				<li>First class CLI support - CLI features like properties, garbage collection and generics are supported directly. And what's more, C++/CLI allows jus to use these features on native unmanaged classes too. 
</li>
				<li>First class C++ support - C++ features like templates and deterministic destructors work on both managed and unmanaged classes. In fact C++/CLI is the only .NET language where you can *seemingly* declare a .NET type on the stack or on the native C++ heap. 
</li>
				<li>Bridges the gap between .NET and C++ - C++ programmers won't feel like a fish out of water when they attack the BCL 
</li>
				<li>The executable generated by the C++/CLI compiler is now fully verifiable. </li>
		</ul>
		<h2>Hello World</h2>
		<pre lang="mc++">
				<span class="cpp-keyword">using</span>
				<span class="cpp-keyword">namespace</span> System;

<span class="cpp-keyword">void</span> _tmain()
{
    Console::WriteLine(<span class="cpp-string">"Hello World"</span>);
}</pre>
		<p>Well, that doesn't look a lot different from old syntax, except that now you don't need to add a reference to <i>mscorlib.dll</i> because the Whidbey compiler implicitly references it whenever you compile with <b>/clr</b> (which now defaults to <b>/clr:newSyntax</b>).</p>
		<h2>Handles</h2>
		<p>One major confusion in the old syntax was that we used the * punctuator with unmanaged pointers and with managed references. In C++/CLI Microsoft introduces the concept of handles.</p>
		<pre lang="mc++">
				<span class="cpp-keyword">void</span> _tmain()
{
    <span class="cpp-comment">//The ^ punctuator represents a handle</span>
    String^ str = <span class="cpp-string">"Hello World"</span>;
    Console::WriteLine(str);
}</pre>
		<p>The ^ punctuator (pronounced as cap) represents a handle to a managed object. According to the CLI specification a handle is a managed object reference. Handles are the new-syntax equivalent of <code lang="mc++"><span class="cpp-keyword">__gc</span></code> pointers in the MC++ syntax. Handles are not to be confused with pointers and are totally different in nature from pointers.</p>
		<h3>How handles differ from pointers?</h3>
		<ul>
				<li>Pointers are denoted using the <code lang="mc++">* </code>punctuator while handles are denoted using the <code>^</code> punctuator. 
</li>
				<li>Handles are managed references to objects on the managed heap, pointers just point to a memory address. 
</li>
				<li>Pointers are stable and GC cycles do not affect them, handles might keep pointing to different memory locations based on GC and memory compactions. 
</li>
				<li>For pointers, the programmer must <code lang="mc++"><span class="cpp-keyword">delete</span></code>explicitly or else suffer a leak. For handles <code lang="mc++"><span class="cpp-keyword">delete</span></code> is optional. 
</li>
				<li>Handles are type-safe while pointers are most definitely not. You cannot cast a handle to a <code lang="mc++"><span class="cpp-keyword">void</span>^</code>. 
</li>
				<li>Just as a <code lang="mc++"><span class="cpp-keyword">new</span></code> returns a pointer, a <code lang="mc++"><span class="cpp-keyword">gcnew</span></code> returns a handle. </li>
		</ul>
		<h2>Instantiating CLR objects</h2>
		<pre lang="mc++">
				<span class="cpp-keyword">void</span> _tmain()
{
    String^ str = <span class="cpp-keyword">gcnew</span> String(<span class="cpp-string">"Hello World"</span>);
    Object^ o1 = <span class="cpp-keyword">gcnew</span> Object();
    Console::WriteLine(str);
}</pre>
		<p>The <code lang="mc++"><span class="cpp-keyword">gcnew</span></code> keyword is used to instantiate CLR objects and it returns a handle to the object on the CLR heap. The good thing about <code lang="mc++"><span class="cpp-keyword">gcnew</span></code> is that it allows us to easily differentiate between managed and unmanaged instantiations. </p>
		<p>Basically, the <code lang="mc++"><span class="cpp-keyword">gcnew</span></code> keyword and the <code>^</code> operator offer just about everything you need to access the BCL. But obviously you'd need to create and declare your own managed classes and interfaces.</p>
		<h2>Declaring types</h2>
		<p>CLR types are prefixed with an adjective that describes what sort of type it is. The following are examples of type declarations in C++/CLI :-</p>
		<ul>
				<li>CLR types 
<ul><li>Reference types 
<ul><li><code lang="mc++"><span class="cpp-keyword">ref</span><span class="cpp-keyword">class</span> RefClass{...};</code></li><li><code lang="mc++"><span class="cpp-keyword">ref</span><span class="cpp-keyword">struct</span> RefClass{...};</code></li></ul></li><li>Value types 
<ul><li><code lang="mc++">value <span class="cpp-keyword">class</span> ValClass{...};</code></li><li><code lang="mc++">value <span class="cpp-keyword">struct</span> ValClass{...};</code></li></ul></li><li>Interfaces 
<ul><li><code lang="mc++"><span class="cpp-keyword">interface</span><span class="cpp-keyword">class</span> IType{...};</code></li><li><code lang="mc++"><span class="cpp-keyword">interface</span><span class="cpp-keyword">struct</span> IType{...};</code></li></ul></li><li>Enumerations 
<ul><li><code lang="mc++"><span class="cpp-keyword">enum</span><span class="cpp-keyword">class</span> Color{...};</code></li><li><code lang="mc++"><span class="cpp-keyword">enum</span><span class="cpp-keyword">struct</span> Color{...};</code></li></ul></li></ul></li>
				<li>Native types 
<ul><li><code lang="mc++"><span class="cpp-keyword">class</span> Native{...};</code></li><li><code lang="mc++"><span class="cpp-keyword">struct</span> Native{...};</code></li></ul></li>
		</ul>
		<pre lang="mc++">
				<span class="cpp-keyword">using</span>
				<span class="cpp-keyword">namespace</span> System;

<span class="cpp-keyword">interface</span><span class="cpp-keyword">class</span> IDog
{
    <span class="cpp-keyword">void</span> Bark();
};

<span class="cpp-keyword">ref</span><span class="cpp-keyword">class</span> Dog : IDog
{
<span class="cpp-keyword">public</span>:
    <span class="cpp-keyword">void</span> Bark()
    {
        Console::WriteLine(<span class="cpp-string">"Bow wow wow"</span>);
    }
};

<span class="cpp-keyword">void</span> _tmain()
{
    Dog^ d = <span class="cpp-keyword">gcnew</span> Dog();
    d-&gt;Bark();
}</pre>
		<p>There, the syntax is now so much more neater to look at than the old-syntax where the above code would have been strewn with double-underscored<br /> keywords like <code lang="mc++"><span class="cpp-keyword">__gc</span></code> and <code lang="mc++">__interface</code>.</p>
		<h2>Boxing/Unboxing</h2>
		<p>Boxing is implicit (yaay!) and type-safe. A bit-wise copy is performed and an <code>Object</code> is created on the CLR heap. Unboxing is explicit - just do a <code lang="mc++"><span class="cpp-keyword">reinterpret_cast</span></code> and then dereference.</p>
		<pre lang="mc++">
				<span class="cpp-keyword">void</span> _tmain()
{
    <span class="cpp-keyword">int</span> z = <span class="cpp-literal">44</span>;
    Object^ o = z; <span class="cpp-comment">//implicit boxing</span><span class="cpp-keyword">int</span> y = *<span class="cpp-keyword">reinterpret_cast</span>&lt;<span class="cpp-keyword">int</span>^&gt;(o); <span class="cpp-comment">//unboxing</span>

    Console::WriteLine(<span class="cpp-string">"{0} {1} {2}"</span>,o,z,y);

    z = <span class="cpp-literal">66</span>; 
    Console::WriteLine(<span class="cpp-string">"{0} {1} {2}"</span>,o,z,y);
}

<span class="cpp-comment">// Output</span><span class="cpp-comment">// 44 44 44</span><span class="cpp-comment">// 44 66 44</span></pre>
		<p>The <code lang="mc++">Object</code><code lang="mc++">o</code> is a boxed copy and does not actually refer the <code lang="mc++"><span class="cpp-keyword">int</span></code> value-type which is obvious from the output of the second <code lang="mc++">Console::WriteLine</code>. </p>
		<p>When you box a value-type, the returned object remembers the original value type. </p>
		<pre lang="mc++">
				<span class="cpp-keyword">void</span> _tmain()
{
    <span class="cpp-keyword">int</span> z = <span class="cpp-literal">44</span>;
    <span class="cpp-keyword">float</span> f = <span class="cpp-literal">33.567</span>;

    Object^ o1 = z; 
    Object^ o2 = f; 

    Console::WriteLine(o1-&gt;GetType());
    Console::WriteLine(o2-&gt;GetType());    
}

<span class="cpp-comment">// Output</span><span class="cpp-comment">// System.Int32</span><span class="cpp-comment">// System.Single</span></pre>
		<p>Thus you cannot try and unbox to a different type.</p>
		<pre lang="mc++">
				<span class="cpp-keyword">void</span> _tmain()
{
    <span class="cpp-keyword">int</span> z = <span class="cpp-literal">44</span>;
    <span class="cpp-keyword">float</span> f = <span class="cpp-literal">33.567</span>;

    Object^ o1 = z; 
    Object^ o2 = f;

    <span class="cpp-keyword">int</span> y = *<span class="cpp-keyword">reinterpret_cast</span>&lt;<span class="cpp-keyword">int</span>^&gt;(o2);<span class="cpp-comment">//System.InvalidCastException</span><span class="cpp-keyword">float</span> g = *<span class="cpp-keyword">reinterpret_cast</span>&lt;<span class="cpp-keyword">float</span>^&gt;(o1);<br /><span class="cpp-comment">//System.InvalidCastException</span>
}</pre>
		<p>If you do attempt to do so, you'll get a <code lang="mc++">System.InvalidCastException</code>. Talk about perfect type-safety! If you look at the IL generated, you'll see the MSIL <code lang="msil">box </code>instruction in action. For example :-</p>
		<pre lang="mc++">
				<span class="cpp-keyword">void</span> Box2()
{
    <span class="cpp-keyword">float</span> y=<span class="cpp-literal">45</span>;
    Object^ o1 = y;
}</pre>
		<p>gets compiled to :-</p>
		<pre lang="msil">.maxstack  <span class="cpp-literal">1</span>
.<span class="cpp-keyword">locals</span> (<span class="cpp-keyword">float32</span> V_0, object V_1)

  ldnull
  <span class="cpp-keyword">stloc</span>.<span class="cpp-literal">1</span><span class="cpp-keyword">ldc</span>.r4     <span class="cpp-literal">45</span>.
  <span class="cpp-keyword">stloc</span>.<span class="cpp-literal">0</span><span class="cpp-keyword">ldloc</span>.<span class="cpp-literal">0</span>
  box   [mscorlib]System.Single
  <span class="cpp-keyword">stloc</span>.<span class="cpp-literal">1</span><span class="cpp-keyword">ret</span></pre>
		<p>According to the MSIL docs, "<i>The box instruction converts the ‘raw’ valueType (an unboxed value type) into an instance of type Object (of type O). This is accomplished by creating a new object and copying the data from valueType into the newly allocated object.</i>"</p>
		<h2>Further reading</h2>
		<ul>
				<li>
						<a href="http://msdn.microsoft.com/msdnmag/issues/04/05/VisualC2005/default.aspx" target="_blank">Write Faster Code with the Modern Language Features of Visual C++ 2005</a> [from MSDN] 
</li>
				<li>
						<a href="http://blog.voidnish.com/index.php?p=11" target="_blank">To C++ or not to C++, that is the question!</a> [from my blog] </li>
		</ul>
		<h2>Conclusion</h2>
		<p>Alright, so why would anyone want to use C++/CLI when they can use C#, J# and that VB thingie for writing .NET code? Here are the four reasons I gave during my talk at DevCon 2003 in Trivandrum (Dec 2003).</p>
		<ul>
				<li>Compile existing C++ code to IL (/clr magic) 
</li>
				<li>Deterministic destruction 
</li>
				<li>Native interop support that outmatches anything other CLI languages can offer 
</li>
				<li>All those underscores in MC++ are gone ;-) </li>
		</ul>
		<!-- Article Ends -->
		<h2>About Nishant Sivakumar</h2>
		<table width="80%" border="0">
				<tbody>
						<tr valign="top">
								<td class="smallText" nowrap="">
										<img src="http://www.codeproject.com/script/profile/images/%7B4042092F-4729-4864-9714-03D49519AF8A%7D.jpg" />
										<br />
										<br />
										<img src="http://www.codeproject.com/script/images/admin_modify.gif" align="absBottom" /> Editor<br /><img src="http://www.codeproject.com/script/images/sitebuild_icon.gif" /> Site Builder</td>
								<td class="smallText" width="100%">Nish is a real nice guy living in Toronto who has been coding since 1990, when he was 13 years old. Originally from sunny Trivandrum in India, he has moved to Toronto so he can enjoy the cold winter and get to play in some snow.<br /><br />He works for The Code Project and handles the Dundas MFC products Ultimate Toolbox, Ultimate Grid and Ultimate TCP/IP that are sold exclusively through The Code Project Storefront. He frequents the CP discussion forums when he is not coding, reading or writing. Nish hopes to visit at least three dozen countries before his human biological mechanism stops working (euphemism used to avoid the use of the d-word here), and regrets that he hasn't ever seen snow until now (will be rectified this December). Oh btw, it must be mentioned that normally Nish is not inclined to speak about himself in the 3rd person. <br /><br />Nish has been a Microsoft Visual C++ MVP since October, 2002 - awfully nice of Microsoft, he thinks. He maintains an MVP tips and tricks web site - <a href="http://www.voidnish.com/" target="_blank">www.voidnish.com</a> where you can find a consolidated list of his articles, writings and ideas on VC++, MFC, .NET and C++/CLI. Oh, and you might want to check out his blog on C++/CLI, MFC, .NET and a lot of other stuff - <a href="http://blog.voidnish.com/" target="_blank">blog.voidnish.com</a><br /><br />Nish loves reading Science Fiction, P G Wodehouse and Agatha Christie, and also fancies himself to be a decent writer of sorts. He has authored a romantic comedy <a href="http://www.vedamsbooks.com/no23584.htm" target="_blank">Summer Love and Some more Cricket</a> as well as a programming book – <a href="http://www.amazon.com/exec/obidos/ASIN/032117352X/" target="_blank">Extending MFC applications with the .NET Framework</a>. 
<p class="smallText">Click <a href="http://www.codeproject.com/script/profile/whos_who.asp?vt=arts&amp;id=20248">here</a> to view Nishant Sivakumar's online profile.</p></td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />  
<h1>C++的管理扩展</h1><p><font class="90v"><b>简介</b><p>C++管理扩展是一组语言扩展，它帮助Microsoft Visual C++开发人员为微软.NET编写应用程序。 </p><p>管理扩展是有用的，如果你： </p><ul><li>希望提高开发人员使用C++编写.NET应用程序的生产率 
</li><li>要分阶段地将一大段代码从非管理C++中移植到.NET平台上 
</li><li>想从.NET Framework应用程序中使用已有的非管理C++组件。 
</li><li>想从非管理C++中使用.NET Framework组件 
</li><li>在同一应用程序中混合非管理C++代码和.NET代码 </li></ul><p><img src="http://www.microsoft.com/china/msdn/archives/others/vstudio/images/chart02.gif" /></p><p>C++管理扩展为开发人员定位.NET Framework提供了无比的灵活性。传统的非管理C++和管理C++代码可以自由地混合在一个<br />应用程序中。用管理扩展编写的应用程序可以利用两种代码的优点。使用管理扩展，现有组件可以方便地封装到.NET组件中，<br />在与.NET集成的同时保留原有投资。 </p><p><b>什么是管理扩展? </b><br />扩展允许你在C++中编写在.NET Framework控制下运行的管理（或.NET）类。（非管理C++类运行在传统的微软基于Windows?<br />的环境中。）一个管理类是一个内置的.NET类，可以完全利用.NET Framework。 </p><p>管理扩展是Visual C++开发系统的新关键字和属性。它们允许开发人员决定哪些类或函数编译为管理或非管理代码。<br />这些部分然后就可以平滑地与其它部分或外部库交互。 </p><p>管理扩展也用于在C++源代码中表示.NET类型和概念。这就允许开发人员容易地编写.NET应用程序，而无需编写额外代码。 </p><p><b>主要使用环境</b></p><ul><li><b>将现有代码平滑地移植到 .NET </b><br />如果你在C++代码上有大量投资，管理扩展将帮你将它们平滑地转移到.NET平台中。因为你可以在一个应用程序-- 
</li><li>甚至是同一文件中混合管理和非管理代码，你可以用很长时间转移代码，一个组件接一个组件地转换到.NET中。 
</li><li>或你可以继续在非管理C++中编写组件，以利用该语言的强大功能和灵活性，只用管理扩展编写少量的高性能的 
</li><li>封装器（它使你的代码可以从.NET组件中调用）。 
</li><li><b>从 .NET语言中访问C++组件 </b><br />管理扩展允许你从任何.NET语言中调用C++类。你需要用扩展编写简单的封装器，它将你的C++类和方法暴露为 
</li><li>管理类。封装器是完全的管理类，可以从任何.NET语言中调用。封装器类是作为了管理类与非管理C++类间的 
</li><li>映射层。它简单地将方法调用直接传递到非管理类中。管理扩展可用于调用任何内置的动态链接库（DLL）及 
</li><li>内置类。 
</li><li><b>从内置代码中访问.NET 类 </b><br />使用管理扩展，你可以创建并从C++代码中直接调用.NET类。你可以编写将.NET组件当作任何其它管理C++类的 
</li><li>C++代码。你可以使用.NET Framework中内置的COM调用.NET类。你使用COM还是使用管理扩展访问.NET组件 
</li><li>要依赖于你的工程。在一些情况下，利用现有的COM支持是最好的选择。在另一些情况下，使用管理扩展可能 
</li><li>会增加性能和开发者的生产率。 
</li><li><b>在同一可执行文件中的管理和内置代码 </b><br />Visual C++编译器能在管理和非管理上下文中自动而透明的翻译数据、指针和指令流。这个过程是允许管理扩展
</li><li>无缝地与非管理代码交互的过程。开发人员能够控制什么样的数据和代码可以管理。选择每个类或函数是管理
</li><li>还是非管理的能力为开发人员提供了更大的灵活性。一些代码或数据类型在非管理环境中执行得要比较好。
</li><li>另一方面，管理代码由于如碎片收集和类库等特性，它提高了开发人员的生产率。现有非管理代码可以一次
</li><li>一部分地转化为管理代码，因此保留了已有的投资。</li></ul></font></p><p></p><img src ="http://www.cppblog.com/mzty/aggbug/2240.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2005-12-29 15:14 <a href="http://www.cppblog.com/mzty/archive/2005/12/29/2240.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Managed, Unmanaged, Native: What Kind of Code Is This?（转）</title><link>http://www.cppblog.com/mzty/archive/2005/11/21/1213.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Mon, 21 Nov 2005 02:47:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2005/11/21/1213.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/1213.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2005/11/21/1213.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/1213.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/1213.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Managed, Unmanaged, Native: What Kind of Code Is This?&nbsp;&nbsp;<a href='http://www.cppblog.com/mzty/archive/2005/11/21/1213.html'>阅读全文</a><img src ="http://www.cppblog.com/mzty/aggbug/1213.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2005-11-21 10:47 <a href="http://www.cppblog.com/mzty/archive/2005/11/21/1213.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>泛型编程 ，知多少？</title><link>http://www.cppblog.com/mzty/archive/2005/11/18/1188.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Fri, 18 Nov 2005 05:51:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2005/11/18/1188.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/1188.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2005/11/18/1188.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/1188.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/1188.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 归纳起来，泛型比非泛型具有下面两个优点：1、&nbsp; 更加安全在非泛型编程中，虽然所有的东西都可以作为Object传递，但是在传递的过程中免不了要进行类型转换。而类型转换在运行时是不安全的。使用泛型编程将可以减少不必要的类型转换，从而提高安全性。2、&nbsp; 效率更高在非泛型编程中，将简单类型作为Object传递时会引起Boxing和Unboxing操作，这两个过程都是具有...&nbsp;&nbsp;<a href='http://www.cppblog.com/mzty/archive/2005/11/18/1188.html'>阅读全文</a><img src ="http://www.cppblog.com/mzty/aggbug/1188.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2005-11-18 13:51 <a href="http://www.cppblog.com/mzty/archive/2005/11/18/1188.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于 “托管与非托管 ” 大家都知道那些，来说说？</title><link>http://www.cppblog.com/mzty/archive/2005/11/18/1186.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Fri, 18 Nov 2005 05:36:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2005/11/18/1186.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/1186.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2005/11/18/1186.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/1186.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/1186.html</trackback:ping><description><![CDATA[<P>与非托管代码互操作?</P>
<P>为了使得现存的非.NET代码都可用，微软的设计使得CLR可以在应用程序里同时包含托管和非托管代码。CLR支持三种互操作：</P>
<P>托管代码调用DLL（就是我们说的动态链接库）中的非托管函数</P>
<P>托管代码使用现存的COM组建（非托管组建作为COM服务器）</P>
<P>非托管代码使用托管类型（托管类型作为COM服务器）</P>
<P><BR>互操作性<BR>是否可以在 .NET 框架程序中使用 COM 对象？<BR>是。您现在部署的任何 COM 组件都可以在托管代码中使用。通常情况下，所需的调整是完全自动进行的。</P>
<P>特别是，可以使用运行时可调用包装 (RCW) 从 .NET 框架访问 COM 组件。此包装将 COM 组件提供的 COM 接口转换为与 .NET 框架兼容的接口。对于 OLE 自动化接口，RCW 可以从类型库中自动生成；对于非 OLE 自动化接口，开发人员可以编写自定义 RCW，手动将 COM 接口提供的类型映射为与 .NET 框架兼容的类型。</P>
<P>是否可以在 COM 程序中使用 .NET 框架组件？<BR>是。您现在创建的托管类型都可以通过 COM 访问。通常情况下，所需的配置是完全自动进行的。托管开发环境的某些新特性不能在 COM 中访问。例如，不能在 COM 中使用静态方法和参数化构造函数。一般，提前确定给定类型所针对的用户是一种较好的办法。如果类型需要在 COM 中使用，您将被限制在使用 COM 可访问的特性。</P>
<P>默认情况下，托管类型可能是可见的，也可能是不可见的，这由用于编写托管类型的语言决定。</P>
<P>特别是，可以使用 COM 可调用包装 (CCW) 从 COM 访问 .NET 框架组件。这与 RCW（请参阅上一个问题）相似，但它们的方向相反。同样，如果 .NET 框架开发工具不能自动生成包装，或者如果自动方式不是您所需要的，则可以开发自定义的 CCW。</P>
<P>&nbsp;是否可以在 .NET 框架程序中使用 Win32 API？<BR>是。使用 P/Invoke，.NET 框架程序可以通过静态 DLL 入口点的方式来访问本机代码库。</P>
<P>下面是 C# 调用 Win32 MessageBox 函数的示例：</P>
<P>using System; <BR>using System.Runtime.InteropServices; </P>
<P>class MainApp <BR>{ <BR>&nbsp;&nbsp;&nbsp; [DllImport("user32.dll", EntryPoint="MessageBox")] <BR>&nbsp;&nbsp;&nbsp; public static extern int MessageBox(int hWnd, String strMessage, String strCaption, uint uiType); </P>
<P>&nbsp;&nbsp;&nbsp; public static void Main() <BR>&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox( 0, "您好，这是 PInvoke！", ".NET", 0 ); <BR>&nbsp;&nbsp;&nbsp; } <BR>}</P>
<P>-----------------------------------------------------------------------------<BR>什么是托管代码和托管数据？</P>
<P>托管代码是为面向公共语言运行库的服务编写的代码（请参阅“什么是公共语言运行库？”）。为了面向这些服务，该代码必须向运行库提供最低级别的信息（元数据）。默认情况下，所有 C#、Visual Basic .NET 和 JScript .NET 代码都受托管。默认情况下，Visual Studio .NET C++ 代码不受托管，但编译器可以通过指定命令行开关 (/CLR) 来产生托管代码。 <BR>与托管代码密切相关的是托管数据（由公共语言运行库的垃圾回收器分配和释放的数据）。默认情况下，C#、Visual Basic 和 JScript .NET 数据受托管。然而，通过使用特殊的关键字可以将 C# 数据标记为非托管。默认情况下，Visual Studio .NET C++ 数据不受托管（即使在使用 /CLR 开关时），但在使用 C++ 托管扩展时，可以通过使用 __gc 关键字将类标记为托管。正如名称所暗示的，这意味着用于类实例的内存受垃圾回收器的托管。另外，类成为 .NET 框架社区的一名完全参与的成员，这既带来了好处，也带来了限制。其中一个好处是与用其他语言编写的类的正确互操作性（例如，托管 C++ 类可以从 Visual Basic 类继承）。其中一个限制是托管类只能从基类继承。</P>
<P>--------------------------------------------------------------------------------<BR>什么是公共语言运行时 (CLR)？<BR>公共语言运行时是 .NET 框架应用程序的执行引擎。</P>
<P>它提供许多服务，包括：</P>
<P>代码管理（加载和执行）</P>
<P><BR>应用程序内存隔离</P>
<P><BR>类型安全验证</P>
<P><BR>IL 到本机代码的转换</P>
<P><BR>元数据（增强的类型信息）访问</P>
<P><BR>为托管对象管理内存</P>
<P><BR>强制代码访问安全</P>
<P><BR>异常处理，包括跨语言异常</P>
<P><BR>托管代码、COM 对象和现有 DLL（非托管代码和数据）之间的互操作</P>
<P><BR>自动进行对象布局</P>
<P><BR>对开发人员服务（配置、调试等）的支持 </P>
<P>什么是公共类型系统 (CTS)？<BR>公共类型系统是多信息类型系统，它被内置在公共语言运行时中，支持大多数编程语言中的类型和操作。公共类型系统支持大量编程语言的完全实现。</P>
<P>&nbsp;</P>
<P>什么是公共语言规范 (CLS)？<BR>公共语言规范是一组结构和限制，用作库编写者和编译器编写者的指南。它使任何支持 CLS 的语言都可以完全使用库，并且使这些语言可以相互集成。公共语言规范是公共类型系统的子集。对于那些需要编写代码供其他开发人员使用的应用程序开发人员，公共语言规范也非常重要。如果开发人员遵循 CLS 规则来设计公共访问的 API，那么就可以在支持公共语言运行时的任何其他编程语言中很容易地使用这些 API。</P>
<P>&nbsp;</P>
<P>什么是 Microsoft 中间语言 (MSIL)？<BR>MSIL 是与 CPU 无关的指令集。.NET 框架程序被编译成 MSIL。它包含加载、存储、初始化和调用对象方法的指令。</P>
<P>与元数据和公共类型系统结合，MSIL 允许真正的跨语言集成。</P>
<P>MSIL 在执行前被转换为机器代码，而不是一边解释一边执行。</P>
<P>&nbsp;</P>
<P>&nbsp;</P><img src ="http://www.cppblog.com/mzty/aggbug/1186.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2005-11-18 13:36 <a href="http://www.cppblog.com/mzty/archive/2005/11/18/1186.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>