本帖最后由 sjdev 于 2010-02-08 19:58:04 编辑

解决方案 »

  1.   

    我以前用过一段时间Vb.net,现在用Vc6.0,很赞同一句话,真正的程序员用C++!
      

  2.   

    以前我用VB Delphi,鼠标拖拖点点一个程序就出来,后来我决定学C++,个人喜好吧。任何语言都一样,必须要学到一定的深度,不然你可以学,别人也可以学,结果就是竞争越来越强
      

  3.   

    C++/CLI是一门独立的语言(比如新的关键字),而不是像C++托管扩展一样是C++的超集 (C++托管扩展有一些不标志的关键字如__gc和__value)。所以,C++/CLI对于这些语法有较大的改变,尤其是去除了一些意义不明确的关键字,增加了一些.NET的特性.在vs2005中可以使用它进行开发。就可以像c#一样调用.NET的Class Library了。标准C++是调不了.NET  de Class Library..可以在MFC下使用标准C++进行开发。 
      

  4.   

    个人也觉得非常别扭,gcnew还好,那个^实在是不习惯。为啥很多人都不看此贴呢?枉费我昨晚写了一个晚上。
      

  5.   


    好,到时候给你个xyz分。
      

  6.   

    最近作SolidWorks开发
    才接触CLI
    感觉还是不如纯C++舒服
    不过对于初学者应该比较合适吧感觉上软件开发的发展模式越来越朝着傻瓜化、普及化发展
    这也应该是必然吧
    而且这样发展必然会在这个领域造成两个极端
    一端是民工级的程序员
    另一端则是专家设计师
      

  7.   

    vc/mfc用的时间最长,穿插使用过C#/PHP/JS
    语言只是一种工具,个人认为没有最好的语言,只有最合适解决问题的语言。
    写程序写到最后只是写出一种解决问题的方案,这个时候是语言无关性的。
      

  8.   

    各位的回答和分析都比较好,那位做SolidWorks的兄弟应该非常熟悉cli了,可以再多多发表一下自己的看法。
      

  9.   

    同意楼上。
    只用过VC/MFC,PHP,本人很懒,不愿学过多的语言。
      

  10.   


    惭愧
    我目前使用ATL的对com的智能指针CComPtr在开发
    没有用CLI
    实在是不适应
    目前正在开发中
    估计年前是出不来了呵呵我个人控制欲比较强
    所以对C++情有独钟
    因为感觉所有东西都在自己的掌握之中
    太多的托管固然省心
    但我认为会使人麻木而不知所然
      

  11.   

    这个感觉微软拿C++来考虑的更多未来的事情。就好比当初微软发展.NET一样,主要目的还是为了使软件开发更加简单。我想AutoCAD采用.NET也是基于这点来考虑的。但是如果把这种面向未来的语言放在现在来看,那么多少就有些不伦不类的感觉了,因为C++已经满足了现在的高性能软件开发需求,而且由于历史的原因目前许多知名的软件也是使用C++来开发的,所以当我们处在C++流行的时代来使用这些面向未来的语言时,不知不觉就会产生这种奇怪的感觉了。不过从另外一个方面来讲,随着软件开发技术的成熟,在软件开发的过程中考虑的更多的不是技术而是需求,就某一个业务来讲不是使用更厉害的语言,而是使用更符合业务需求的技术。低成本,高效率。
      

  12.   

        刚毕业就进了一家搞AutoCAD二次开发的公司,如楼主帖子中提到的,AutoCAD是紧跟MS脚步。
        后来公司做的一个项目中就用到C++/CLI,那时是2008年,用的是VS2005,整个开发过程可是说是极其杯具的,也可能是对这个新事物的不熟悉,出现了很多莫名其妙的情况,咨询AutoCAD的相关部门他们也不太清楚,而网上的资料是少之又少。后来公司决定仅仅在连接oracle数据库部分使用CLI也许以后随着.net framework的普及,CLI的开发应用会越来越广,但C++和CLI的混合编程,个人不看好。
      

  13.   

    to xianglitian:
    各种语言各有优势,使用ATL开发的优势就是轻便。c++/cli的优势是什么?快捷?
    to songsu:
    我赞成你的看法,我觉得c++/cli是微软的战略,至于未来,等看微软了。to M_S_D_N:
    autocad的开发在国内还是比较多的,autocad使用没使用wpf也不得而知.
    不过个人感觉,如果autocad跟ms的脚步也算是一种策略,现在做设计的,多半是windows平台。
      

  14.   

    我没有采用c++/cli做开发
    对c++/cli也不甚了解
    所以没有什么发言权不过感觉上c++/cli类似于C#
    所以上手快应该是它最大的特点吧
    而且让后编程人员没有后顾之忧
    我觉得这一点对于像我这样搞二次开发的人尤为重要
    毕竟是该人家的东西
    善后的工作是繁琐、必需的但却是多余的工作拙见而已
    还望斧正
      

  15.   

    to xianglitian:
    c++/cli是c++和c#的结合体,我也不甚了解.
    ps,兄台是搞SolidWorks二次开发?to jennyvenus:
    mvp,你发表一下自己的看法吧。
      

  16.   

    我不是专门作SolidWorks二次开发的
    只是现阶段公司有需求
    内部使用
    我就研究一下
      

  17.   

    如果用c++/clr ,为什么不直接使用C#呢?
      

  18.   

    俺没什么可说的,俺的行业只有三种语言可用,一种是c,一种是汇编,一种是java,java也是java卡上的java,是java的一个很小的子集,俺们没事自己也用C写写java卡虚拟机。
      

  19.   

    to jennyvenus:俺没什么可说的,厉害啊.
      

  20.   

    用过两年VC/MFC,现在正在学习C#。
      

  21.   

    如果说C++难,难度是100分,那么一般来说,Java也就40分的难度,C#是60分的难度,Ruby也差不多65分吧。
    但是我要给C++/CLI打分到130分 除非特殊情况,千万别用。比如说ManagedSpy,就是C++/CLI写的,因为它确实比C#快,而且可以更好地使用C++资源。我相信这样的机会不多
    我研究过一段时间,但是发现,这个东西太不实际了:
    http://www.cnblogs.com/healerkx/articles/1206239.html
    这是当时写的一部分blog,本来打算一直写的,算了费劲啊
      

  22.   

    这是我第一篇讲C++/CLI技术本身的文章,涉及到了这样一个话题,就是ref class instance in stack style。而且这个名字是我自己创造的,因为我实在不知道是不是有文档论述这个问题。就当我孤陋寡闻而谈之吧。
    [Code]
    ref class A
    {
    public:
        A(int a) :_a(a)    { }
        ~A() { }
    private:
        int _a;
    };int main()
    {
        A^ a2 = gcnew A(9);
        
        A a3(5); //Look   
        return 0;
    }代码就这么简单,关键需要注意的是//Look行的代码,至少在我发现这个代码可以正确编译之前,我一直以为ref class只能通过gcnew创建对象呢。但是这种语法形式是怎么样创建对象的呢?我看过汇编了,我发现这种写成stack style的方式,做的事情几乎等同于用gcnew做得事情。
    我们先明确一件事情,就是标准C++是如何创建一个堆对象的。
    T* p = new T;
    我们都很清楚,它只做了两件重要的事情,第一,调用operator new,分配内存;第二,在这块内存上,调用构造函数,创建对象。
    而我们强调这个,就是想说明C++/CLI中调用gcnew会做哪些事情,汇编代码很清楚地告诉了我们。
        29:     A^ a2 =  gcnew A(9);
    0000008a  mov         ecx,1015B28h 
    0000008f  call        FF9B53A4 
    00000094  mov         esi,eax 
    00000096  mov         ecx,esi 
    00000098  mov         edx,9 
    0000009d  call        dword ptr ds:[01015B68h] ;****
    000000a3  mov         dword ptr [ebp-3Ch],esi 
        30:     
        31:     A a3(5);
    000000a6  mov         ecx,1015B28h 
    000000ab  call        FF9B53A4 
    000000b0  mov         esi,eax 
    000000b2  mov         ecx,esi 
    000000b4  mov         edx,5 
    000000b9  call        dword ptr ds:[01015B68h] ;****
    000000bf  mov         dword ptr [ebp-34h],esi 
    000000c2  mov         eax,dword ptr [ebp-34h] 
    000000c5  mov         dword ptr [ebp-2Ch],eax
    以上代码,注意这个地址[FF9B53A4],我有理由怀疑它就是gcnew的函数地址。而下面一句,
    call        dword ptr ds:[01015B68h]
    很明白了,这个是在调用ref class A的构造函数。
    剩下不一样的代码,只是多了两个mov指令,说白了,就是多赋值了。所以,我觉得给出等价的C++/CLI代码更直观地说明问题。以下是等效的C++/CLI代码:
        A^ a4 = gcnew A(4);
        A const% a4_ = *a4;
    其中,ecx,1015B28h,目前我只有个猜测。先写上,等遇到明白的朋友再请教。
    根据我调试C++的经验,忘ecx里面mov地址,往往指代一个对象的指针,相当于this指针。而我们又相对确定call FF9B53A4是在调用gcnew。
    并且根据我的试验代码,其中gcnew A(),和gcnew B(),编译出来的代码,在mov ecx, ***,这里的***是根据类型的不同而不同的。
    所以,我只能给出我猜想的伪码:ref class A
    {};class Class_A
    {
        A^ operator gcnew();
    }A^ a = Singleton<Class_A>::Instance().operator gcnew();
    ##注意啊,上面的是伪码。关于其析构函数,也有许多话题可以说
    1. 我们为ref class A提供了析构函数,那么写成这种创建形式的代码后,编译器会在函数调用后,调用该对象的析构函数,这点与标准C++非常相似。
    但是有一点疑惑的是,我显式地调用delete,如:
    A^ a2 = gcnew A(9);
    delete a2;
    它对应的汇编代码为:
    0000009c 8B 45 C8         mov         eax,dword ptr [ebp-38h] 
    0000009f 89 45 CC         mov         dword ptr [ebp-34h],eax 
    000000a2 83 7D CC 00      cmp         dword ptr [ebp-34h],0 
    000000a6 74 11            je          000000B9 
    000000a8 8B 4D CC         mov         ecx,dword ptr [ebp-34h] 
    000000ab FF 15 24 00 9C 00 call        dword ptr ds:[009C0024h] 
    000000b1 33 D2            xor         edx,edx 
    000000b3 89 55 D4         mov         dword ptr [ebp-2Ch],edx 
    000000b6 90               nop              
    000000b7 EB 05            jmp         000000BE 
    000000b9 33 D2            xor         edx,edx 
    000000bb 89 55 D4         mov         dword ptr [ebp-2Ch],edx而由编译器自动生成的代码则是:
    000000f4 8B 4D D0         mov         ecx,dword ptr [ebp-30h] 
    000000f7 FF 15 1C 00 9C 00 call        dword ptr ds:[009C001Ch]
    注意Bold的ASM代码,它们的差别在于,可能是前者调用了delete,尽管它还是要去调用析构函数,而后者直接调用析构函数,也许这个就是差别吧。(猜测)
    所以说只是猜测,因为我实验了如下的代码,结果让我很不解:
        A a3(5);
        a3.~A();
    当我们显式地调用析构函数的时候,编译器编译出来的代码,call指令的操作数,与上面二者皆是不同的,但是也可以走到析构函数中,所以我在想,这三个地址,是不是仅仅是转发器而已,而并不是析构函数的地址呢?
    这有什么意义呢?我目前想到的就是Lock模式,尽管C++/CLI可以享受垃圾回收了,但是依然有对象需要我们去显式地delete,于是这样创建的 ref class对象,就是一个智能指针,尽管Native的Class也完全可以做到这样一点。如果我发现有更适于ref class对象的Lock,而不是Native class对象的Lock,我会补充这部分代码的。
    需要补充的是,以往的经验,似乎也不是很灵了。例如,如果我们希望禁止这种写法,以往的C++经验告诉我们,可以把析构函数变为protected成员;然而,对于这个ref class来说,根本不起作用,访问权限控制不会发生效力(我很失望)。编译依然会成功。再看那段等效的C++/CLI代码
    再看那段等效的C++/CLI代码:
        A^ a4 = gcnew A(4);
        A const% a4_ = *a4;
    这段代码的等效程度几乎是95%的。因为我观察到的ASM指令,和内存变化,分明就是将A a3(5);编译成了这样的两行代码。从内存的变化上看,也确实存在着等效的临时变量a4,最后,我看到栈上两个同样值的4个字节,分别就是a4和 a4_。
    问题来了,那么a4和a4_的类型分别是什么呢?
    变量a4是一个句柄,类型是A^,这是没有争议的。那么a3和a4_是不是等价的呢?我现在还不能完全确定。
    但是凭借以往学习标准C++的经验来看,a3和a4_,也许并不能完全等价,或许我需要构造出一段代码,才能证实或证伪。不过我还是先把“以往的C++眼光”说出来。
    class C {};C c1;C* p = new C;
    C const& c2 = *p;
    这里,c1是C类型的对象,而c2只是一个引用类型,要初始化才能使其具有别名的价值。我就是凭借这一点,认为a3与a4_并不是完全等价的。而a4与a4_的内存布局是完全一样的,这就让我想起了标准C++中指针和引用的关系了,引用虽然不是指针,但是却往往是用指针来实现的。这样,凭借对标准C++的认识,而且又在*与&的关系,^与%的关系上,找到了一个非常吻合的契合点。于是我才大胆地写下了这些推测。
      

  23.   

    受教了,clr里的^号看的实在别扭
      

  24.   

    如果说C++难,难度是100分,那么一般来说,Java也就40分的难度,C#是60分的难度,Ruby也差不多65分吧。但是我要给C++/CLI打分到130分 除非特殊情况,千万别用。比如说ManagedSpy,就是C++/CLI写的,因为它确实比C#快,而且可以更好地使用C++资源。我相信这样的机会不多-------------------------------------------------------
    呵呵,
    熟悉C#的人不会考虑用C++/CLI,在.net下C# + wpf差不多了;
    熟悉C++的人不会考虑用C++/CLI,在win2下 c++ + winapi差不多了;需要兼顾开发效率和运行效率的,估计会考虑c++/cli。healer_kx兄文章写的不错,建议继续写下去,我看关注的人还挺多。
      

  25.   


    我写blog的时候,看到错别字了,也要进去修改一下,时间久了,好像关注的人就多了,其实都是我自己。~
      

  26.   

    是CLI吧?别扭极了,看了一下CLI的东西简直要崩溃了,还是C++更好些
      

  27.   

    以现在MS的策略看,很重视WPF和Silverlight什么的,所以就别说C++/CLI了,C++的走势都看低啊。
      

  28.   


    这就是我要讨论的关键,
    事实上,使用C#开发wpf,silverlight很方便的说。
    如果要使用c++开发wpf,需要通过clr。
    所以我在想,是不是……??如此而已。
      

  29.   

    我不知道C++能不能开发WPF,
    感觉
    1,理论上应可以,
    2,完全没那个必要你应该比我还清楚才对。而且从Silverlight的角度看,那个客户端的插件,能运行MSIL是可以了,但是没法运行C++的Native Code吧,而且不安全啊。C++的地位好尴尬,从那个排行榜看,C在上升,C++在下降这就说明趋势了
    未来开发几大趋势,手机移动平台开发(看好,Java),Web应用开发,(这个不好说,Flex和Silverlight都不错。)
    再有就是云计算,云计算是Ruby也好,Python也罢,或者Java,但是肯定没有C++的份额。
    -----------------------------------------------------------------------------------------
    但是我很喜欢C++。!
      

  30.   

    我没有用过。。用C++/clr 还不如用C++ 做成COM ,然后在C#中调用呢。
      

  31.   

    呵呵,首先c++/clr是个商品,为啥微软要捣鼓这个东东,光从技术上是得不到答案滴楼主有心,有时间思考这些,赞一个,羡慕一个,o(∩_∩)o...
      

  32.   

    不懂.net这东东...以前学了点VB...前段时间玩了一阵子J2SE...目前在看标准C++...
    要是WINAPI也能像JAVA的类那样封装...我想在WIN平台的编程就方便多了...看了一个多星期的MFC...还是看不出个所以然....C#..CLR 什么的..没打算去接触...
      

  33.   

    就是把C++改造成适合.net开发的语言, 还不如直接上C#, 它才是MS的亲儿子.
    不过偶尔托管/非托管混编确实很方便。
      

  34.   

    to甘草兄,如果不用cli,c++可以进行wpf开发吗?
      

  35.   

    俺觉得
    做C++和C#的胶合层比较合适一些。
    对于一个C++程序员来说C++/CLI难度不应该比C++大。
      

  36.   

    03年用过c++的托管编程,是为一个c#的B\S项目作控件,语法适应之后也没什么不习惯的.
    不过C#和C++一起写,有时候概念就混乱了
      

  37.   

    C++/CLI很容易学,但概念很多。它最大的用处就是混合本地代码和托管代码,好处是可以无缝的给.NET应用提供框架库无法满足的功能。也就是编写扩展模块。当然如果只是写本地代码或.NET代码,建议不要用它,无论哪一方面它都没有优势,只有结合使用使才有必要。这是我的一点理解。
      

  38.   

    我只在写界面的时候用到C++/CLR调用.net库
    业务逻辑都是标准C++写的,托管C++只用来写界面。
    不得不承认用.net库写界面还是非常方便的,
    比MFC好用不知道多少倍,用过MFC的人应该都有体会。C++比较尴尬的是缺乏很多实用的库,尤其是界面库,而.net库正好弥补了这个缺陷
    所以C++/CLR存在的唯一目的我感觉就是为了C++能调用.net库我想到的C++能用的界面库QT,GTK+,MFC
    MFC先不说它,用过MFC写界面的人没一个喜欢它的。
    QT确实很好,非常面向对象,我用过半年做过两个项目,后来就没用过了,
    比较讨厌的是它的布局编辑器感觉太业余了,还有那个moc,感觉很山寨。
    不过那个时候还是QT3.2.3版本,现在已经不知道升级到什么版本了,是不是还有这些却问题就不知道了。
    GTK+是linux下移植过来的,用的不多,不好多评论,不过个人感觉也非常好用,至少比MFC强太多了。不过写界面最重要的是什么?
    方便,快速!没人喜欢写个界面写一大坨代码的。
    那么界面编辑器就很重要了,VS的界面编辑在我用过的各种IDE中是最好的了。
      

  39.   

    C++/CLI 有点像C# 也有点像C++ 各种感觉就是C++加了一堆不知名的东西 value class 和ref class 。。还有perproty 和 索引[] 。。个人感觉多余了。。重载几个函数 几个运算符 都一样。。正在看event 。事件和委托。。一头雾水ing....