有多少人在使用C++/CLR?
本帖最后由 sjdev 于 2010-02-08 19:58:04 编辑 有多少人在使用C++/CLR?
每年的编程语言排行榜出来以后,都照例会有人对编程语言现状进行概述并对未来的趋势做简要预测。如果有人胆敢以“XXX语言已死,@@@语言形式一片大好”的言论来表明自己的立场,多说情况下会立刻招致其他语言开发人员的围追堵截。我不想挑起语言之争和平台之争,所以我使用了一个比较温和的疑问句“有多少人在使用C++/CLI?”我是想了解一下行情并为自己的以后做一些简单的准备。希望知道和不知道的、了解和不了解的、熟悉和不熟悉的兄弟姐妹,叔叔阿姨,大妈大伯都发表一下自己的看法。如果我下面的哪句话触动了你的神经,请保持平常心、淡定;如果我下面的哪句话给了你启发,你也不妨留下自己的话给我一些启发;如果我下面的哪句话你完全不同意,很好,说明这个问题值得讨论。好吧,我简单说说我的情况和看法吧。
各种编程语言中,我使用最多的是C++(使用VC6,7,8,9做开发);曾使用C#做过项目,上学的时候学过Java,VB,毕业后简单学习了VBScript、WSH、批处理(如果这也算是一种语言的话)和JScript,机缘巧合之下简单了解了WPF;对Perl、Python有浓厚的兴趣(还没有去学习它们)。除了Java以及还没有学习的Perl和Python外,可勉强使用其它学过的语言进行相应的开发。如果真要说方便的话,我觉得还是脚本最方便,很简单的代码往往可以完成强大的功能。但是咱也不能用脚本去做整个开发吧?开发上的方便,得数C#,若不是速度上的限制,估计使用C#的开发者比现在要多一些。C++/VC/MFC就不作评判了,据说只有明智的开发者才会选择C++/VC/MFC,评判它们就表示自己不明智。
这两天看到VC/MFC论坛里有人问了一些C++/CLI的问题。于是我的问题就出来了,问题1:现在有多少人在使用C++/CLR?使用C++/CLR的初衷是什么?使用C++/CLR带来的好处是什么?在我的印象中,CLI是很奇怪的东西,它是为了兼容CLR,从C++搞过来的不伦不类的东西(注:这里“不伦不类”是中性词)。当然了,C++/CLI也算是一种独立编程语言。Microsoft对为什么使用C++/CLI有自己的一套说法,可是我更愿意听到来自民间的说法,我们不能“被代表”。刚毕业时,我曾从Microsoft网站了Down了一些webcast教程,其中一套教程就是李建忠讲的C++/CLI。抱着勇于尝试新事物的想法,我简单了解了C++/CLI。从那之后的很长一段时间内,我都没有创建过VC/MFC下的CLR项目,因为我觉得怪怪的。我相信坛子里稍微比我早个一两年毕业的兄弟可能都了解托管C++,而C++/CLI就是它的马甲(我自己这么认为)。早些年的托管C++臭名昭著,那现在的C++/CLI呢?
我使用C#做.net开发时,才明白CLR的含义。原来,凡是兼容CLR的,各种东西都可以拿来用,这不和COM的思想有很多相似之处吗?于是我开始严格执行孔老夫子的“温故而知新”理论,煞有介事地创建了一个VC/MFC的CLR项目。虽然很快就Shift+Delete了这个项目,好歹也算真真切切地感受了一下。我们都知道,C#就是为.net平台而生的一种编程语言,如果操作系统自带了.net framework,那C#就成了操作系统内置支持的开发语言(一如linux之于gcc/g++/c++)。我的第二个问题来了:徘徊在C#和C++之间,C++/CLI有什么前景?
我使用WPF的时间很短,并且只是做了一个简单的3D程序,不敢发表什么感受。我觉得未来这个方面的开发者会越来越多。Vista sp1和Win7都已经自带了.net framework,这样一来发布程序时就不用担心庞大的.net framework了。事实上,很多大型的程序如AutoCAD等早就开始使用.net了,最新版的AutoCAD可能都已经在使用WPF了,庞大的安装程序使得它们不在乎多上个.net framework。要进行WPF开发,使用xaml和C#是最方便的,基本不需要额外的设置。如果使用C++进行开发,操作上需要费一些周折,最后可能还得转到CLR支持上来。难道,这是C++/CLI的最终目的?
好了,我迷迷糊糊地讲了一通个人所见所闻,最终也没表达清楚自己的立场。那么,究竟多少人在使用C++/CLR呢?
注:有的地方是C++/CLI,有的地方是C++/CLR。它们可以说是相同的,也可以说是不同的。如果你认为它们是相同的,它们就是相同的;同样的,如果你认为它们是不同的,那它们就是不同的。
如有其它信息,请留言:blog.csdn.net/sjdev
[解决办法]
我以前用过一段时间Vb.net,现在用Vc6.0,很赞同一句话,真正的程序员用C++!
[解决办法]
没有时间不断熟悉新的语言。
[解决办法]
没有人回复之前貌似可以编辑。
[解决办法]
以前我用VB Delphi,鼠标拖拖点点一个程序就出来,后来我决定学C++,个人喜好吧。任何语言都一样,必须要学到一定的深度,不然你可以学,别人也可以学,结果就是竞争越来越强
[解决办法]
再补充一下,真的喜欢编程的人我个人觉的应该学C++或者C,如果为了赚钱而学编程,学什么都一样
[解决办法]
C++/CLI是一门独立的语言(比如新的关键字),而不是像C++托管扩展一样是C++的超集 (C++托管扩展有一些不标志的关键字如__gc和__value)。所以,C++/CLI对于这些语法有较大的改变,尤其是去除了一些意义不明确的关键字,增加了一些.NET的特性.在vs2005中可以使用它进行开发。就可以像c#一样调用.NET的Class Library了。
标准C++是调不了.NET de Class Library..可以在MFC下使用标准C++进行开发。
[解决办法]
觉得非常别扭,会用也不用~
简直是用手穿鞋去走路。。。
[解决办法]
哈哈哈哈,帮你顶一下!
新年快乐!
[解决办法]
vc+汇编~~~~~~~~~~~~`
[解决办法]
最近作SolidWorks开发
才接触CLI
感觉还是不如纯C++舒服
不过对于初学者应该比较合适吧
感觉上软件开发的发展模式越来越朝着傻瓜化、普及化发展
这也应该是必然吧
而且这样发展必然会在这个领域造成两个极端
一端是民工级的程序员
另一端则是专家设计师
[解决办法]
vc/mfc用的时间最长,穿插使用过C#/PHP/JS
语言只是一种工具,个人认为没有最好的语言,只有最合适解决问题的语言。
写程序写到最后只是写出一种解决问题的方案,这个时候是语言无关性的。
[解决办法]
帮你顶一下!
新年快乐!
[解决办法]
只用过VC/MFC,PHP,本人很懒,不愿学过多的语言。
[解决办法]
惭愧
我目前使用ATL的对com的智能指针CComPtr在开发
没有用CLI
实在是不适应
目前正在开发中
估计年前是出不来了呵呵
我个人控制欲比较强
所以对C++情有独钟
因为感觉所有东西都在自己的掌握之中
太多的托管固然省心
但我认为会使人麻木而不知所然
[解决办法]
这个感觉微软拿C++来考虑的更多未来的事情。就好比当初微软发展.NET一样,主要目的还是为了使软件开发更加简单。我想AutoCAD采用.NET也是基于这点来考虑的。
但是如果把这种面向未来的语言放在现在来看,那么多少就有些不伦不类的感觉了,因为C++已经满足了现在的高性能软件开发需求,而且由于历史的原因目前许多知名的软件也是使用C++来开发的,所以当我们处在C++流行的时代来使用这些面向未来的语言时,不知不觉就会产生这种奇怪的感觉了。
不过从另外一个方面来讲,随着软件开发技术的成熟,在软件开发的过程中考虑的更多的不是技术而是需求,就某一个业务来讲不是使用更厉害的语言,而是使用更符合业务需求的技术。低成本,高效率。
[解决办法]
刚毕业就进了一家搞AutoCAD二次开发的公司,如楼主帖子中提到的,AutoCAD是紧跟MS脚步。
后来公司做的一个项目中就用到C++/CLI,那时是2008年,用的是VS2005,整个开发过程可是说是极其杯具的,也可能是对这个新事物的不熟悉,出现了很多莫名其妙的情况,咨询AutoCAD的相关部门他们也不太清楚,而网上的资料是少之又少。后来公司决定仅仅在连接oracle数据库部分使用CLI。。。也许以后随着.net framework的普及,CLI的开发应用会越来越广,但C++和CLI的混合编程,个人不看好。
[解决办法]
关注下!
.
[解决办法]
我没有采用c++/cli做开发
对c++/cli也不甚了解
所以没有什么发言权
不过感觉上c++/cli类似于C#
所以上手快应该是它最大的特点吧
而且让后编程人员没有后顾之忧
我觉得这一点对于像我这样搞二次开发的人尤为重要
毕竟是该人家的东西
善后的工作是繁琐、必需的但却是多余的工作
拙见而已
还望斧正
[解决办法]
基本上只会基本C。
[解决办法]
我不是专门作SolidWorks二次开发的
只是现阶段公司有需求
内部使用
我就研究一下
[解决办法]
如果用c++/clr ,为什么不直接使用C#呢?
[解决办法]
混个眼熟。。。。(回复内容太短了)
汗。。再加几个....
[解决办法]
俺没什么可说的,俺的行业只有三种语言可用,一种是c,一种是汇编,一种是java,java也是java卡上的java,是java的一个很小的子集,俺们没事自己也用C写写java卡虚拟机。
[解决办法]
用过两年VC/MFC,现在正在学习C#。
[解决办法]
呵呵,。
[解决办法]
如果说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,本来打算一直写的,算了。。。费劲啊。。。
[解决办法]
这是我第一篇讲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++的认识,而且又在*与&的关系,^与%的关系上,找到了一个非常吻合的契合点。于是我才大胆地写下了这些推测。
[解决办法]
受教了,clr里的^号看的实在别扭
------解决方案--------------------