|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
在性能方面,在windows平台下,.net网页编程可能是占强项,要是把.net网页编程放在sun开发的操作系统上去运行呢?根本就运行不了,.net网页编程对其它操作系统的支持也很弱,性能也可能比不上java。下载源代码1、媒介
从第五回入手下手到第七回,我们用ATL写了一个复杂的COM组件,之以是说复杂,是由于在组件中,只完成了一个自界说(custom)的接口IFun。固然假如想偷懒的话,我们能够把200个函数都加到这一个接口中,果然云云的话,生怕就没有人喜好利用我们这个组件了。一个组件既然能够供应多个接口,那末我们在计划的时分,就应当依照函数的功效举行分类,把分歧功效分类的函数用多个接口体现出来。如许能够有以下的一些优点:
1、一个接口中的函数个数无限、功效会合,利用者简单进修、影象和挪用。一个接口究竟供应几个函数符合那?谜底是:假如你是黑猩猩,那末一个接口最多3个函数,假如你是人,那末一个接口最好不要凌驾7个函数。(注1)
2、简单保护。最少你肉眼搜刮的时分也便利一些呀。
3、简单晋级。当我们给组件增添函数的时分,不要修正已宣布的接口,而是供应一个新的接口来完乐成能扩大。(注2)
本回书下落在------怎样完成一个组件,多个接口。
2、接口布局
<br>
、组件A有2个自界说接口,组件B是A的晋级
某日,我们计划了组件A,它有2个自界说(custom)接口。IMathe有函数Add()完成整数加法,IStr有函数Cat()完成字符串联接。忽一日,我们晋级组件A到B,欲增添一个函数Mul()完成整数的乘法。注重,因为我们已宣布了组件A,因而我们不克不及把这个函数布置到老接口IMathe中了。办理办法是再界说一个新接口IMathe2,在新接口中增添Mul()函数并仍旧保存Add()函数。如许,老用户不晓得新接口IMathe2的存在,他仍旧利用旧接口IMathe;而新用户则能够丢弃IMathe,间接利用IMathe2的新接口功效。看,多平顺的晋级体例呀!
3、完成
3-1、起首用ATL完成一个自界说(custom)接口IMathe的COM组件,在接口中完成Add()整数加法函数。注重!!!必定是自界说(custom)的接口(dual双接口今后再先容)。假如你不懂得这个操纵,请从头浏览“第五回”或“第六回”。3-2、检察IDL文件。完成上一个步骤后,翻开IDL文件,内容以下:(称号及UUID会和你程序中的IDL有所分歧)- 1import"oaidl.idl";2import"ocidl.idl";3 [4object,5uuid(072EA6CA-7D08-4E7E-B2B7-B2FB0B875595),6helpstring("IMatheInterface"),7pointer_default(unique)8 ]9 interfaceIMathe:IUnknown10 {11[helpstring("methodAdd")]HRESULTAdd([in]longn1,[in]longn2,[out,retval]long*pnVal);12 };13[14 uuid(CD7672F7-C0B4-4090-A2F8-234C0062F42C),15 version(1.0),16 helpstring("Simple31.0TypeLibrary")17]18librarySIMPLE3Lib19{20 importlib("stdole32.tlb");21 importlib("stdole2.tlb");22 [23uuid(C6F241E2-43F6-4449-A024-B7340553221E),24helpstring("MatheClass")25 ]26 coclassMathe27 {28[default]interfaceIMathe;29 };30};
复制代码 1-2引进IUnknown和ATL已界说的别的接口形貌文件。import相似与C言语中的#include3-12一个接口的完全形貌4object暗示本块形貌的是一个接口。IDL文件是借用了PRC远程数据互换格局的申明办法5uuid(......)接口的IID,这个值是ATL主动天生的,能够手工修正或用guidgen.exe发生(注3)6在某些软件或工具中,能看到这个提醒7界说接口函数中参数所利用指针的默许属性(注4)9接口叫IMathe派生自IUnknown,因而IMathe接口的头三个函数必定就是QueryInterface,AddRef和Release10-12接口函数列表13-30范例库的完全形貌(范例库的观点今后再说),上面所申明的行,是必要先懂得的18#import时分的默许定名空间23组件的CLSID,CoCreateInstance()的第一个参数就是它27-29接口列表28[default]暗示谁供应了IUnknown接口
3-3、手工修正IDL文件,黑体字部分是手工输出的。完成后保留。- import"oaidl.idl";import"ocidl.idl";[object,uuid(072EA6CA-7D08-4E7E-B2B7-B2FB0B875595),helpstring("IMatheInterface"),pointer_default(unique)]interfaceIMathe:IUnknown{[helpstring("methodAdd")]HRESULTAdd([in]longn1,[in]longn2,[out,retval]long*pnVal);}; [ //所谓手工输出,实在也是有技能的:把下面的接口形貌(IMathe)复制、粘贴上去,然后再改更便利哈object,uuid(072EA6CB-7D08-4E7E-B2B7-B2FB0B875595),//手工或用工具发生的IIDhelpstring("IStrInterface"),pointer_default(unique)]interfaceIStr:IUnknown{//今朝还没有任何接口函数};[uuid(CD7672F7-C0B4-4090-A2F8-234C0062F42C),version(1.0),helpstring("Simple31.0TypeLibrary")]librarySIMPLE3Lib{importlib("stdole32.tlb");importlib("stdole2.tlb");[uuid(C6F241E2-43F6-4449-A024-B7340553221E),helpstring("MatheClass")]coclassMathe{[default]interfaceIMathe;interfaceIStr; //别忘了呦,这里另有一个那};};
复制代码 3-4、翻开头文件(Mathe.h),手工增添类的派生干系和接口出口表,然后保留。- classATL_NO_VTABLECMathe:publicCComObjectRootEx<CComSingleThreadModel>,publicCComCoClass<CMathe,&CLSID_Mathe>,publicIMathe, //别忘了,这里加一个逗号publicIStr //增添一个基类{public:CMathe(){}DECLARE_REGISTRY_RESOURCEID(IDR_MATHE)DECLARE_PROTECT_FINAL_CONSTRUCT()BEGIN_COM_MAP(CMathe) //接口出口表。这里填写的接口,才干被QueryInterface()找到COM_INTERFACE_ENTRY(IMathe)COM_INTERFACE_ENTRY(IStr)END_COM_MAP()
复制代码 3-5、好了,统统停当。接上去,就能够在IStr接口中增添函数了。示例程序中增添一个字符串联接功效的函数:
HRESULTCat([in]BSTRs1,[in]BSTRs2,[out,retval]BSTR*psVal);假如你不晓得怎样做,请从头浏览前三回的内容。
4、接口晋级
我们这个组件已刊行了,但溘然一天我们必要在IMathe接口上再增添一个函数......不可!相对不克不及在IMathe上间接修正!怎样办?办理办法是------再增添一个接口,我们就叫IMathe2吧,假如今后还要增添函数,那末我们再增添一个接口叫IMathe3......子子孙孙,无量尽也。
4-1、修正IDL文件,实在假如你了解了下面一大节的内容,再增添一个接口是很复杂的事变了。- import"oaidl.idl";import"ocidl.idl";[object,uuid(072EA6CA-7D08-4E7E-B2B7-B2FB0B875595),helpstring("IMatheInterface"),pointer_default(unique)]interfaceIMathe:IUnknown{[helpstring("methodAdd")]HRESULTAdd([in]longn1,[in]longn2,[out,retval]long*pnVal);};[object,uuid(072EA6CB-7D08-4E7E-B2B7-B2FB0B875595),helpstring("IStrInterface"),pointer_default(unique)]interfaceIStr:IUnknown{[helpstring("methodCat")]HRESULTCat([in]BSTRs1,[in]BSTRs2,[out,retval]BSTR*psVal);}; [object,uuid(072EA6CC-7D08-4E7E-B2B7-B2FB0B875595),helpstring("IMathe2Interface"),pointer_default(unique)]interfaceIMathe2:IUnknown{ //上面这个Add()函数,只要IDL中的声明,而不必增添任何程序代码,由于这个函数早在IMathe中就已完成了[helpstring("methodAdd")]HRESULTAdd([in]longn1,[in]longn2,[out,retval]long*pnVal);};[uuid(CD7672F7-C0B4-4090-A2F8-234C0062F42C),version(1.0),helpstring("Simple31.0TypeLibrary")]librarySIMPLE3Lib{importlib("stdole32.tlb");importlib("stdole2.tlb");[uuid(C6F241E2-43F6-4449-A024-B7340553221E),helpstring("MatheClass")]coclassMathe{[default]interfaceIMathe;interfaceIStr;interfaceIMathe2; //别忘了,这里另有一行呢!};};
复制代码 4-2、翻开头文件,增添派生干系和接口出口表- classATL_NO_VTABLECMathe:publicCComObjectRootEx<CComSingleThreadModel>,publicCComCoClass<CMathe,&CLSID_Mathe>,publicIMathe,publicIStr, //这里增添一个逗号publicIMathe2{public:CMathe(){}DECLARE_REGISTRY_RESOURCEID(IDR_MATHE)DECLARE_PROTECT_FINAL_CONSTRUCT()BEGIN_COM_MAP(CMathe)COM_INTERFACE_ENTRY(IMathe)COM_INTERFACE_ENTRY(IStr)COM_INTERFACE_ENTRY(IMathe2)END_COM_MAP()
复制代码 4-3、示例程序中,增添了一个整数乘法函数:
HRESULTMul([in]longn1,[in]longn2,[out,retval]long*pnVal);假如你不晓得怎样做,那就别学了:-(都讲好几遍了,怎样还不把握呢?晓得狗熊是怎样逝世的吗?(注5)
4-4、由于我们的组件晋级了,因而也应当修正版本号了(这不是必需的,但最好修正一下)。翻开注册表文件(.rgs)把有关ProgID的版本"Mathe.1"修正为"Mathe.2"。别的假如你乐意,把IDL文件中的version和提醒笔墨一并修正一下。这里就不再粘贴文件内容了,由于很复杂,人人下载示例程序(注6)后,本人看吧。
5、小结
为故国的软件奇迹而搏斗!
下回书先容“主动化”---IDispatch接口,好玩的很!感谢存眷:-)
注1:黑猩猩的瞬时影象量是3,人类的瞬时影象量是7。迷信家做过实行,当着面,把一块糖扣在3个碗的个中之一,黑猩猩能立即正确找到,但假如凌驾3个碗,猩猩就晕了......假如给你看一串数字,然后立即让你说出来,一样平常的人只会记得个中的7个。
注2:组件一经宣布,就不要修正已有接口。如许软件的晋级才干做到“鲁棒”性。
注3:guidgen.exe工具,在《COM组件计划与使用(二)》中已先容。
注4:组件函数对内存指针的处置,今后有专门的章回会商。
注5:笨逝世的!
注6:示例程序有两部分,分离是vc6.0版本和vc.net2003版本。
原文链接:http://www.vckbase.com/document/viewdoc/?id=1501
对于一个大型项目,如果用java来作,可能需要9个月,并且可能需要翻阅10本以上的书,但如果用ruby来作,3个月,3本书就足够了,而.net网页编程也不过3,4本书足以,这就是区别。 |
|