JAVA网站制作之COM组件计划与使用(二)GUID 和 接口仓酷云
windows系统样,他们做了什么事或者留了一些后门程序,谁都不知道,二,java开发是跨平台,任何系统上都可以运行,对于保密型系统和大型系统开发这是必要的1、媒介书接上回,话说在doc(Word)复合文件中,已办理了保留xls(Excel)数据的成绩了。那末,接上去又要办理另外一个成绩:当WORD程序读取复合文件,碰到了xls数据的时分,它该怎样启动Excel呢?启动后,又怎样让Excel本人往读进、剖析、显现xls数据呢?
2、CLSID观点
有一个十分复杂的办理计划,那就是在对象数据的后面,保留有处置这个数据的程序名。(见下图左上)
<br>
、CLSID的观点
这切实其实是一个复杂的办法,但同时成绩也很严峻。在“张三”的盘算机上,Excel的路径是:"c:officeExcel.exe",假如把这个doc文件复制到“李四”的盘算机上利用,而“李四”的Excel的路径是:
"d:ProgramfilesMicrosoftOfficeOfficeExcel.exe",垮台了:-(
因而,微软想出了一个办理计划,那就是不利用间接的路径暗示办法,而利用一个叫CLSID(注1)的体例直接形貌这些对象数据的处置程序路径。CLSID实在就是一个号码,大概说是一个16字节的数。察看注册表(上图),在HKCRCLSID{......}主键下,LocalServer32(DLL组件利用InprocServer32)中保留着程序路径称号。CLSID的布局界说以下:
typedefstruct_GUID{DWORDData1; //随机数WORDData2; //和工夫相干WORDData3; //和工夫相干BYTEData4; //和网卡MAC相干}GUID;typedefGUIDCLSID;//组件IDtypedefGUIDIID;//接口ID#defineREFCLSIDconstCLSID&//罕见的声明和赋值办法CLSIDCLSID_Excel={0x00024500,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};struct__declspec(uuid("00024500-0000-0000-C000-000000000046"))CLSID_Excel;classDECLSPEC_UUID("00024500-0000-0000-C000-000000000046")CLSID_Excel;//注册表中的暗示办法{00024500-0000-0000-C000-000000000046} 用一个号码直接暗示程序名,切实其实是个Goodidea,完成了组件地位的通明性,并便利地扩大出DCOM(远程组件)。但,但,但,但.....CLSID有16个字节共128位二进制数,干嘛用这么长的数字呀?遐想昔时......我还在上幼儿园的时分,人们计划了socket,用TCP/IP协定举行收集通信。每一个介入通信的盘算机都有一个4字节的IP暗示编号地点,局限是0,0,0,0~255,255,255,255共42亿个地点。但是没想到啊,没想到,自从Internet选择了TCP/IP协定后,42亿个地点就不敷全球的休息国民分派啦。除休息国民,另有冰箱、彩电、电饭锅、手机、手提电脑......这些都必要连网呀。在办公室经由过程收集开启电饭锅给我焖饭,上班回家后就可以吃现成的啦,多幸运呀?!(注:在我们家妻子是向导,以是是我做饭。咳......)
因为前车可鉴,微软此次计划CLSID/IID就利用了GUID观点的16个字节,这下好啦,全球60亿生齿,每一个人每秒钟分派10亿个号码,那末必要分派1800亿年。归正比及地球没有了都不会利用完的:-)
3、发生CLSID
[*]假如利用开辟情况编写组件程序,则IDE会主动帮你发生CLSID;
[*]你能够手工写CLSID,但万万不要和人家已天生的CLSID反复呀,以是严峻地不保举;(但是微软的CLSID都是手工写的,这叫“只许明知故犯,不准公民点灯”);
[*]程序中,能够用函数CoCreateGuid()发生CLSID;
[*]利用工具发生GUID(注2);
vc6.0版本运转:"vc目次CommonToolsGuidGen.exe"程序(你能够参照上回文章中先容的办法,把这个工具程序加到开辟情况中,便利挪用)。vc.net版本,在菜单“工具创立GUID”中,就能够实行了。4、ProgID观点
每个COM组件都必要指定一个CLSID,而且不克不及重名。它之以是利用16个字节,就是要从几率上包管反复是“不成能”的。可是,(天下上就怕“可是”二字)微软为了利用便利,也撑持另外一个字符串称号体例,叫ProgID(注3)。见上图注册表的ProgID子键内容(注4)。因为CLSID和ProgID实际上是一个观点的两个分歧的暗示情势,以是我们在程序中能够任意利用任何一种。(有些人就是厌恶,措辞不算数。明显GUID的目标就是克制反复,但竟然又同意利用ProgID?!ProgID是一个字符串的名字,反复的大概性就太年夜了呀。赶明儿我也写个程序,我盘算这个程序的ProgID叫“Excel.Application”,嘿嘿)上面先容一下CLSID和ProgID之间的转换办法和相干的函数:
函数功效申明CLSIDFromProgID()、CLSIDFromProgIDEx()由ProgID失掉CLSID。没甚么好说的,你本人都能够写,查注册表贝ProgIDFromCLSID()由CLSID失掉ProgID,挪用者利用完成后要开释ProgID的内存(注5)CoCreateGuid()随机天生一个GUIDIsEqualGUID()、IsEqualCLSID()、IsEqualIID()对照2个ID是不是相称StringFromCLSID()、StringFromGUID2()、StringFromIID()由CLSID,IID失掉注册表中CLSID款式的字符串,注重开释内存5、接口(Interface)的来源
到此,我们已晓得了CLSID或ProgID独一地暗示一个组件服务程序,那末依据这些ID,就能够加载运转组件,并为客户端程序供应服务了。(启动组件程序的办法,会连续先容)。接上去先会商怎样挪用组件供应的函数?-----接口。
作为客户端程序员,它但愿大概说他请求:我的程序只写一次,然后不做任何修正就能够挪用恣意一个组件。举例来讲:
[*]你能够在Word中嵌进Excel,也能够嵌进Picture,也能够嵌进任何第三方宣布的ActiveX文档......也就是说,连Word本人都不晓得利用它的人将会在doc内里拔出甚么东东;
[*]你能够在HTML文件中拔出一个ActiveX,也能够拔出一个程序剧本Script,......你本人写的插件也能够拔出到IE情况中。为了完成你的功效,你相对也不会往让微软修正IE吧?!
这个请求其实有点难度,Office开辟停止了。说来话巧,一天老O(Office项目标总工程师)和小B(VB项目标总工程师)一同饮酒,老O向小B倾吐了他的懊恼:
老O:怎样能让我写的程序C,能够挪用别的人写的程序S中的函数?(C暗示客户程序,S暗示供应服务的程序)
小B:你是否是喝懵懂了?让S作成DLL,你往LoadLibrary()、GetProcAddress()、...FreeLibrary()?!
老O:空话!如果这么复杂就行了。成绩是,连我都不晓得这个S程序是干甚么的?无能甚么?我怎样挪用呀?
小B:哦......这个对照初级,但我如今不克不及告知你,由于我怕你印象不深。
老O:~!·#¥%……—*......
小B:是如许的,在VB中,我们制订了一个尺度,这个尺度同意任何一个VB开辟者,把他本人写的某个功效的小程序放在VB的工具栏上,如许就好象他扩大了VB的功效一样。
老O:哦?就是谁人叫甚么VBX的滥玩艺儿?
小B:我呸......别看VBX这个工具不起眼儿,切实其实我也没看上它。但你猜怎样着?如今有不计其数的VB程序喜好者把他们写的形形色色功效的VBX小程序,放到网上,让人人共享那。
老O:哦~~~,那你们的这个VBX尺度是甚么?
小B:嘿嘿......实在特复杂,就是在VBX中必需完成7个函数,这7个函数称号和功效必需是:初始化、开释、显现、动静处置......,而至于它外部想干甚么,我也管不着。我只是在必要的时分挪用我必要的这7个函数。
老O:哦~~~,如许呀......对了,我现有个急事,我先走了。88,你付帐吧......
小B:喂!喂喂......走这么急干甚么,钱包都失落了:-)
老O固然丢了钱包,仍旧镇静地冲回办公室,他入手下手了思索......
1、我的程序C,要能挪用任何人写的程序B。那末B必需要依照我事前的请求,供应我必要的函数F1(),F2(),F3(),K1(),K2()。
2、BASIC是注释实行,因而它的函数不必思索誊写按次,只需给出函数名,注释器就可以找到。但我利用的是C++呀......
3、C++编译后的代码中没有函数名,只要函数地点,因而我必需改善为用VTAB(虚函数表)暗示函数出口:
<br>
、VTAB的布局
4、还不敷好,必要改善一下,由于一切的函数地点都放在一个表中会不天真、欠好修正、不容易扩大。恩,有了!依照函数功效的范例举行分类:
<br>
、多个VTAB的布局
5、成绩又来了,如今有2个VTAB虚函数表,那末怎样可以从一个表找到另外一个表那?恩又有举措了,我请求你必需要完成一个函数,而且这个函数地点必需放在一切表的开首(表中的第一个函数指针),这个函数就叫QueryInterface()吧,完成从一个表查找到另外一个表的功效:(除QueryInterface()函数,特地也完成别的两个函数,叫AddRef()和Release()。这两个函数的功效今后再说)
<br>
、COM接口布局
6、为了今后形貌便利,不再利用上图(图四)的办法了,而利用图五如许简便的款式:
<br>
、COM接口布局的简便图示
6、接口(Interface)观点
1、函数是经由过程VTAB虚函数表供应其地点,从另外一个角度来看,不论用甚么言语开辟,编译器发生的代码都能天生这个表。如许就完成了组件的“二进制特征”轻松完成了组件的跨言语请求。
2、假定有一个指针型变量保留着VTAB的首地点,则这个变量就叫“接口指针”(注6),变量定名的时分,习气上加上"I"开首。别的为了辨别分歧的接口,每一个接口也都要有一个名字,该名字就和CLSID一样,利用GUID体例,叫IID。
3、接口一经宣布,就不克不及再修正了。否则就会呈现向前兼容的成绩。这本性质叫“接口稳定性”。
4、组件中必需有3个函数,QueryInterface、AddRef、Release,它们3个函数也构成一个接口,叫"IUnknown"。(注7)
5、任何接口,实在都包括了IUnknown接口。跟着你打仗到更多的接口就会了更体味解到接口的另外一本性质“承继性”。
6、在任何接口上,挪用表中的第一个函数,实在就是挪用QueryInterface()函数,就失掉你想要的别的一个接口指针。这本性质叫“接口的传送性”
7、C/C++言语中必要事前对函数声明,那末就会请求组件也必需供应C言语的头文件。不可!为了能使COM具有跨言语的才能,决意不再为任何言语供应对应的函数接口声明,而是自力地供应一个叫范例库(TLB)的声明。每一个言语的IDE情况本人往依据TLB天生本人言语必要的包装。这本性质叫“接口声明的自力性”(注8)
7、客户程序与组件之间的协商挪用
回到我们的上一个话题,Word中嵌进一个组件,那末Word是怎样协商利用这个组件的那?上面是容器和组件之间的一个摹拟对话历程:
容器协商部分组件应对部分1依据CLSID启动组件。
CoCreateInstance()天生对象,实行机关函数,实行初始化举措。2你有IUnknown接口吗?有,给你!3恩,太好了,那末你有IPersistStorage接口吗?(注9)
IUnknown::QueryInterface(IID_IPersistStorage...)没有!4真低劣,连这个都没有。那你有IPersistStreamInit接口吗?(注10)
IUnknown::QueryInterface(IID_IPersistStreamInit...)哈,这个有,给!5好,好,这还差未几。你如今给我初始化吧。
IPersistStreamInit::InitNew()OK,初始化完成了。6完成了?好!如今你读数据往吧。
IPersistStreamInit::Load()读完啦。我依据数据,已在窗口中显现出来了。7好,如今我们各自处置用户的鼠标、键盘动静吧............8哎呀!用户要保留加入程序了。你的数据被用户修正了吗?
IPersistStreamInit::IsDirty()改了,用户已修正啦。9那好,那末用户修正后,你的数据必要多年夜的存储空间呀?
IPersistStreamInit::GetSizeMax()恩,我算算呀......好了,统共必要500KB。10晕,你这么个小玩意竟然占用这么年夜空间?!......好了,你能够存了。
IPersistStreamInit::Save()感谢,我已存好了。11恩。拜拜了您那。(注11)
IPersistStreamInit::Release();IUnknown::Release()实行析构函数,删除对象。12我本人也该加入了......
PostQuitMessage()
容器(大概说客户端)就是如许和组件举行对话,协商挪用的。假如组件甲完成了IA接口,那末容器就会利用它,假如组件乙没有供应IA接口,可是它供应了IB接口,那末容器就会挪用IB接口的函数......云云,容器程序基本就不必要晓得组件究竟是干甚么的,组件究竟是用甚么言语开辟的,组件的磁盘地位究竟在那里,它都能够一般运转。太奇奥了!太出色了!怎一个“爽”字了得!
8、小结
第二回中,先容了两个十分主要的观点:CLSID和Interface。因为全篇都是观点形貌而没有示例程序相共同,大概读者的了解还不太深切、不完全。别发急,我们即刻就要进进到组件程序计划阶段了,到谁人时分,你依据详细的程序代码,再回过火来再次浏览本回文章,没读懂?哦......再读!渐渐地您白叟家就懂了:-)
留功课啦......
1、IDispatch接口的IID是几?(哎~~~笨笨,在源程序中,用鼠标右键实行Gotodefinition呀)
2、IPicture接口有几个函数?功效是甚么?(别玩了!你多年夜了?想不想在程序中显现JPG图象呀,看MSDN往)
想晓得为何COM函数老是前往HRESULT吗?想晓得怎样利用BSTR、VARIANT吗?想晓得COM中应当怎样利用内存吗?想晓得怎样利用UNICODE吗?......恩~~~,我如今不克不及告知你,我如今告知你,怕你印象不深!且听下回分化......
注1:CLSID=ClassID上回书已先容了把CLSID写进复合文件的函数:WriteClassStg()、IStorage::SetClass()。
注2:GUID全局独一标示符,CLSID/IID实际上是借用了GUID的观点。
注3:ProgID=ProgramID,等价于CLSID,是用字符串暗示的。
注4:注册表子键ProgID和VersionIndependentProgID分离暗示真实的ProgID和版本有关的ProgID。好比在我盘算机上安装的Excel,它的ProgID="Excel.Application.9",而VersionIndependentProgID="Excel.Application"。
注5:COM组件的内存办理,见后续的文章。
注6:Interface=接口,之前微软不叫它接口,而叫协定Protocol。实在我到以为这个词更贴切一些。
注7:IUnknown这个名字起的好,竟然叫“我不晓得”:-),它的IID叫IID_IUnknown,假如用注册表款式暗示,那末它的值是{00000000-0000-0000-C000-000000000046}。
注8:TLB是由一个形貌接口的文件IDL经由编译发生的。IDL的申明,见后续的文章吧。
注9:IPersistStorage是用复合文件的存储(Storage)功效来保留/读取数据用的一个接口。
注10:IPersistStreamInit是用复合文件的流(Stream)功效来保留/读取数据用的一个接口。
注11:拜拜了您那=英语北京话,再会。
原文链接:http://www.vckbase.com/document/viewdoc/?id=1485
从一个编程语言的普及程度来将,一个好的IDE是至关中要的,而现在的java的IDE虽然已经很好了,但是和.net网页编程比起来还是稍微差一些的,这是个客观事实。java要想普及的更好。DE是必须加以改进的。 吧,现在很流行的Structs就是它的一种实现方式,不过Structs用起来实在是很繁,我们只要学习其精髓即可,我们完全可以设计自己的MVC结构。然后你再研究一下软件Refactoring (重构)和极限XP编程,相信你又会上一个台阶。 做完这些,你不如整理一下你的Java代码,把那些经典的程序和常见的应用整理出来,再精心打造一番,提高其重用性和可扩展性。你再找几个志同道合的朋友成立一个工作室吧 是一种由美国SUN计算机公司(Sun Microsystems, Inc.)所研究而成的语言 接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。 接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。 设计模式是高级程序员真正掌握面向对象核心思想的必修课。设计模式并不是一种具体"技术",它讲述的是思想,它不仅仅展示了接口或抽象类在实际案例中的灵活应用和智慧 Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、ServerSocket等。Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。 一般学编程语言都是从C语开始学的,我也不例外,但还是可能不学过程语言而直接学面向对象语言的,你是刚接触语言,还是从C开始学比较好,基础会很深点,如果你直接学习JAVA也能上手,一般大家在学语言的时候都记一些语言的关键词,常有的包和接口等。再去做逻辑代码的编写,以后的学习过程都是从逻辑代码编写中提升的,所以这方面都是经验积累的。你要开始学习就从 是一种使网页(Web Page)由静态(Static)转变为动态(Dynamic)的语言 多重继承(以接口取代)等特性,增加了垃圾回收器功能用于回收不再被引用的对象所占据的内存空间,使得程序员不用再为内存管理而担忧。在 Java 1.5 版本中,Java 又引入了泛型编程(Generic Programming)、类型安全的枚举、不定长参数和自动装/拆箱等语言特性。 另外编写和运行Java程序需要JDK(包括JRE),在sun的官方网站上有下载,thinking in java第三版用的JDK版本是1.4,现在流行的版本1.5(sun称作J2SE 5.0,汗),不过听说Bruce的TIJ第四版国外已经出来了,是专门为J2SE 5.0而写的。 Jive的资料在很多网站上都有,大家可以找来研究一下。相信你读完代码后,会有脱胎换骨的感觉。遗憾的是Jive从2.5以后就不再无条件的开放源代码,同时有licence限制。不过幸好还有中国一流的Java程序员关注它,外国人不开源了,中国人就不能开源吗?这里向大家推荐一个汉化的Jive版本—J道。Jive(J道版)是由中国Java界大名 鼎鼎的banq在Jive 2.1版本基础上改编而成, 全中文,增加了一些实用功能,如贴图,用户头像和用户资料查询等,而且有一个开发团队在不断升级。你可以访问banq的网站 吧,现在很流行的Structs就是它的一种实现方式,不过Structs用起来实在是很繁,我们只要学习其精髓即可,我们完全可以设计自己的MVC结构。然后你再研究一下软件Refactoring (重构)和极限XP编程,相信你又会上一个台阶。 做完这些,你不如整理一下你的Java代码,把那些经典的程序和常见的应用整理出来,再精心打造一番,提高其重用性和可扩展性。你再找几个志同道合的朋友成立一个工作室吧 一直感觉JAVA很大,很杂,找不到学习方向,前两天在网上找到了这篇文章,感觉不错,给没有方向的我指了一个方向,先不管对不对,做下来再说。 是一种语言,用以产生「小应用程序(Applet(s)) 吧,现在很流行的Structs就是它的一种实现方式,不过Structs用起来实在是很繁,我们只要学习其精髓即可,我们完全可以设计自己的MVC结构。然后你再研究一下软件Refactoring (重构)和极限XP编程,相信你又会上一个台阶。 做完这些,你不如整理一下你的Java代码,把那些经典的程序和常见的应用整理出来,再精心打造一番,提高其重用性和可扩展性。你再找几个志同道合的朋友成立一个工作室吧 J2SE开发桌面应用软件比起 VC,VB,DEPHI这些传统开发语言来说,优势好象并不明显。J2ME对于初学者来说,好象又有点深奥,而且一般开发者很难有开发环境。 学Java必读的两个开源程序就是Jive和Pet Store.。 Jive是国外一个非常著名的BBS程序,完全开放源码。论坛的设计采用了很多先进的技术,如Cache、用户认证、Filter、XML等,而且论坛完全屏蔽了对数据库的访问,可以很轻易的在不同数据库中移植。论坛还有方便的安装和管理程序,这是我们平时编程时容易忽略的一部份(中国程序员一般只注重编程的技术含量,却完全不考虑用户的感受,这就是我们与国外软件的差距所在)。 应用在电视机、电话、闹钟、烤面包机等家用电器的控制和通信。由于这些智能化家电的市场需求没有预期的高,Sun公司放弃了该项计划。随着1990年代互联网的发展
页:
[1]