《com组件对象与.net类对象的相互转换(二).docx》由会员分享,可在线阅读,更多相关《com组件对象与.net类对象的相互转换(二).docx(6页珍藏版)》请在优知文库上搜索。
1、com组件对象与.net类对象的相互转换(二)COM组件对象与.NET类对象的相互转换(二)作者:独孤九剑email:mikaiyue日期:8/14/20014:49:50PM2.实例演示一(不显示定义接口)创建一个最简洁的C#Console工程,其程序如下所示:usingSystem;usingSystem.Runtime.InteropServices;namespaceCSharpServer/缺省的是ClassInterfaceType.AutoDispatch,该方式下只生成dispatch接口只能被运用script,VB等Iatebinding方式的COM客户运用ClassInte
2、rfaceAttribute(ClassInterfaceType.AutoDual)publicclassSharpObjectprivatestringmStrName;publicSharpObject()publicstringName/Property:Name,Get/Setget(returnm_strName;setmstrName=value;(2)在工程的属性中设置RegisterforCOMinterop为Trueo这样编译后就会生成CSharpServer.tlb文件,并且自动将其注册。吩咐行吩咐regasm有同样的效果。注册表内容如卜丁HKEY-C1.SSES-RTC
3、1.SID88994E22-E99F-320B-908C-96E32B7BFE56gCSharPSerVer.SharpObjectInprocServer32dll=C:WINNTSystem32mscoree.ThreadingModcl=BothAssembly=CSharpServer,Culture=11cutral,RuntimeVersion=Vl.Class=CSharpServer.SharpObjectVersion=1.O.583.39183,PublicKeyToken=nul1O.2914CodeBase=fi1c:/E:/cm/netC%23exerCSharpSe
4、rverbin/Debug/CSharpServer.dllProgId=CSharPServer.SharpObjectCSharpServer.tlb文件中包含了组件的类型库信息,包括C1.SID.IID,接口定义等。而组件的真正实现,对.NET对象的调用则是由通用语言运行时库mscoree.dll完成的。可以说mscoree.dl1和CSharpServer.tlb加起来就是runtime为CSharPSerVer这个.NET类生成的CCWo(3)写一个简洁的VBScript程序test.vbs,如下所示:DimobjSetobj=CreateObject(CSharpServer.Sh
5、arpObject)obj.Name=ChangMingMsgBoxMyNameisobj.Name双击该文件,胜利运行。(4)创建一个最简洁的MFC对话框工程,加入以下代码:/这里应当用rawinterfaces_only,因为SharPObjeCt缺省的从ObjCC假如不加这个选项的话,也要为Object的公用函数和属性生成包装函数,而ObjeCt:GetTyPe返回Type型,而没有为类Type生成包装接口,所以编译时会出错#import.CSharpServerbindebugCSharpServer.11braw_interfaces_on1yno_namespacenamed_gu
6、ids.CoInitia1.ize(NU1.1.);方法一因为运用了raw_interfaces_only,所以没有生成属性Name的包装函数GetName,PutName.SharpObjectPtrpSharpObject(_Uuidof(SharpObject);pSharpObject-put_Name(_bstr_t(ChangMing);BSTRStrName:PSharPObjeCt-get_Name(StrName);AfxMessageBox(MyNameis+_bstr_t(strName):方法二*_SharpObject*pSharpObjcct=NU1.1.;HRES
7、U1.Thr=CoCreateInstance(C1.SID_SharpObject,null,Clsctxjnprojserver,IID_SharpObject,(void*)pSharpObject);if(SUCCEEDED(hr)pSharpObject-put_Name(_bstr_t(ChangMing);BSTRstrName;pSharpObject-get_Name(strName):AfxMessageBox(MyNameis+_bstr_t(strName);PSharpObject-ReleaseO;elseAfxMessageBox(error);*/CoUnini
8、tialize();自动生成的classinterface中,接口名是+类名,即_SharPObjeCto除此之外,运用方式与调用一般的COM对象完全一样。(5)运用CIaSSinterface的缺点在于.ET类的变更会影响到COM客户。详细而言,对于运用Script.VB等latebinding方式的语言如test,vbs,NET类的变更对其没有影响。而对于earlybinding的客户,因为dispid与其在.ET类中的位置相关,所以.NET类的变更很有可能会变更成员的dispid,从而会影响到客户程序,客户程序须要重新编译。对于通过指针干脆调用的C+客户程序,每次.NET的重新编译都会导
9、致其重新编译,因为classinterface的IID每次都是随机生成的!所以MS剧烈要求不要运用这种方式,classinterface不能算是一个真正的接口,它总是不断的变更,这违反了接口的精神,违反了COM的精神。3、实例演示二(显示定义接口)(1)创建一个最简洁的C#Console工程,其程序如下所示:usingSystem;usingSystem.Runtime.InteropServices:namespaceCSharpServer2假如不指定guid,每次都Guid(539448DE-9F3B-4781-1F6-F3C852091FC9)会随机生成IlDpublicinterfa
10、ceISharpObject2stringName/Property:Name,Get/Setget;set;voidTestO;假如不指定guid,每次都会随机生成C1.SIDGuid(F5A31AAB-FAA9-47cc-9A73-E35606114CE8)publicclassSharpObjectzpublicSharpObject2O/Property:Name,m_strName;m_strNanie=value;publicvoidTest():ISharp0bject2privatestringm_strName;publicstringNameGet/Setgetreturn
11、set(2)在工程的属性中设置RegisterforCOMinterop为True这样编译后就会生成CSharpServer2.tlb文件,并且自动将其注册。注册表内容如下:HKEY_C1.ASSES_ROOTC1.SIDF5A31AAB-FA9-47CC-9A73-E35606114CE8=CSharPSerVe12SharpObject2InprocServer32=C:WINNTSysteni32mscoree.dl1ThreadingModel=BothClass=CSharpServer2.SharpObject2Assembly=CSharpServer2,Version=I.0.
12、583.38696,Culture=neutral,PublicKeyToken=nul1RuntimeVersion=Vl.0.2914CodeBase=file:/E:/cmnetC%23exerCSharpServer2binDebugCSharpServer2.dl1ProgId=CSharpServer2.Sharp0bject2(3)创建一个最简洁的MFC对话框工程,加入以下代码:这里不用raw_interfaces_only,因为Sharp0bject2只从接口ISharPObjCCt2继承而ISharPObjeC12没有父类,所以不会有SharpObject那样的编译错误#im
13、port.CSharpServer2bindebugCSharpScrver2.tlbno_namespacenamed_guids.(CoInitialize(NU1.1.);方法一ISharp0bject2PtrpSharp0bject2(_uuidof(SharpObjec12);pSharp0bject2-PutName(ChangMing);AfxMessageBox(MyNameis+pSharp0bject2-GetName();方法二i*ISharpObject2*pSharp0bject2=NU1.1.:HRESU1.Thr=CoCreatelnStanCe(C1.SID_SharPobjeCt2,NU1.1.,C1.SCTX_INPROC_SERVER,HDSharPObjee12,(void*)pSharp0bject2);if(SUCCE印ED(hr)pSharpObJect2-PutName(ChangMing);AfxMessageBox(MyNameis+pSharpObject2-GetNameO);pSharp0bject2-ReleaseO;elseAfxMessageBox(error);*/CoUninitialize();只有接口ISharp0bject2保持不变,就不会影响到COM客户程序。