乐观 发表于 2015-1-18 11:37:07

JAVA网页编程之COM组件计划与使用(三)数据范例仓酷云

C#是不行的,比如说美国的航天飞船里就有java开发的程序以上是我的愚见,其实不管那种语言,你学好了,都能找到好的工作,1、媒介
  上回书先容了GUID、CLSID、IID和接口的观点。本回的重点是先容COM中的数据范例。咋还不先容组件程序的计划步骤呀?咳......别发急,别发急!孔子曰:“饭要一口一口地吃”;老子语:“心急吃不了热豆腐”,孙子云:“走一步看一步吧”......先把握需要的常识,未来写出发序来才会轻车熟路也:-)
  走进正题之前,请人人紧紧记着一条准绳:COM组件是运转在散布式情况中的。好比,你写了一个组件程序(DLL或EXE),那末利用者多是在本机的某个历程内加载组件(INPROC_SERVER);也多是从另外一个历程中挪用组件的历程(LOCAL_SERVER);也多是在这台盘算机上挪用地球何处盘算机上的组件(REMOTE_SERVER)。以是在了解和计划的时分,要每时每刻想起这句话。快!拿出小本本,记上去!

2、HRESULT函数前往值
  每一个人在做程序计划的时分,都有他们各自的哲学头脑。拿函数前往值来讲,就有很多多少种情势。
 函数前往值前往值信息doublesin(double)浮点数值
盘算正玄值BOOLDeleteFile(LPCTSTR)布尔值
文件删除是不是乐成。如失利,必要GetLastError()才干获得失利缘故原由void*malloc(size_t)内存指针
内存请求,假如失利,前往空指针NULLLONGRegDeleteKey(HKEY,LPCTSTR)整数
删除注册表项。0暗示乐成,非0失利,同时这个值就反应了失利的缘故原由UINTDragQueryFile(HDROP,UINT,LPTSTR,UINT)整数
获得拖放文件信息。以分歧的参数挪用,则前往分歧的寄义:
一会儿暗示文件个数,一会儿暗示文件名长度,一会儿暗示字符长度...............
............
  云云纷纷庞大的前往值,云云寄义多变的前往值,使得人人在进修和利用的过程当中,增添了分外的坚苦。好了,COM的计划标准终究对他们举行了一致。组件API及接口指针中,除IUnknown::AddRef()和IUnknown::Release()两个函数外,别的一切的函数,都以HRESULT作为前往值。人人设想一个组件的接口函数好比叫Add(),完成2个整数的加法运算,在C言语中,我们能够以下界说:
longAdd(longn1,longn2){returnn1+n2;}  还记得方才我们说的准绳吗?COM组件是运转在散布式情况中的。也就是说,这个函数大概运转在“地球另外一边”的盘算机上,既然运转在那末悠远的中央,就有大概呈现服务器关机、收集失落线、运转超时、对方不在服务区......等非常。因而,这个加法函数,除必要前往运算了局之外,还应当前往一个值------函数是不是被一般实行了。HRESULTAdd(longn1,longn2,long*pSum){*pSum=n1+n2;returnS_OK;}  假如函数一般实行,则前往S_OK,同时真实的函数运转了局则经由过程参数指针前往。假如碰到了非常情形,则COM体系经由判别,会前往响应的毛病值。罕见的前往值有:
 HRESULT值寄义S_OK0x00000000乐成S_FALSE0x00000001函数乐成实行完成,但前往时呈现毛病E_INVALIDARG0x80070057参数有毛病E_OUTOFMEMORY0x8007000E内存请求毛病E_UNEXPECTED0x8000FFFF未知的非常E_NOTIMPL0x80004001未完成功效E_FAIL0x80004005没有具体申明的毛病。一样平常必要获得RichError毛病信息(注1)E_POINTER0x80004003有效的指针E_HANDLE0x80070006有效的句柄E_ABORT0x80004004停止操纵E_ACCESSDENIED0x80070005会见被回绝E_NOINTERFACE0x80004002不撑持接口
<br>
、HRESULT的布局

  HRESULT实际上是一个双字节的值,其最高位(bit)假如是0暗示乐成,1暗示毛病。详细拜见MSDN之"StructureofCOMErrorCodes"申明。我们在程序中假如必要判别前往值,则可使用对照运算标记;switch开关语句;也能够利用VC供应的宏:
HRESULThr=挪用组件函数;if(SUCCEEDED(hr)){...}//假如乐成......if(FAILED(hr)){...}//假如失利......3、UNICODE
  盘算机创造后,为了在盘算机中暗示字符,人们制订了一种编码,叫ASCII码。ASCII码由一个字节中的7位(bit)暗示,局限是0x00-0x7F共128个字符。他们觉得这128个数字就充足暗示abcd....ABCD....1234这些字符了。
  咳......说英语的人就是“笨”!厥后他们俄然发明,假如必要依照表格体例打印这些字符的时分,短少了“制表符”。因而又扩大了ASCII的界说,利用一个字节的全体8位(bit)来暗示字符了,这就叫扩大ASCII码。局限是0x00-0xFF共256个字符。
  咳......说中文的人就是伶俐!中国人使用一连2个扩大ASCII码的扩大地区(0xA0今后)来暗示一个汉字,该办法的尺度叫GB-2312。厥后,日文、韩文、阿拉伯文、台湾繁体(BIG-5)......都利用相似的办法扩大了当地字符集的界说,如今一致称为MBCS字符集(多字节字符集)。这个办法是出缺陷的,由于各个国度区域界说的字符集有交集,因而利用GB-2312的软件,就不克不及在BIG-5的情况下运转(显现乱码),反之亦然。
  咳......说英语的人终究变“伶俐”一些了。为了把全球国民一切的一切的笔墨标记都一致举行编码,因而制订了UNICODE尺度字符集。UNICODE利用2个字节暗示一个字符(unsignedshorint、WCHAR、_wchar_t、OLECHAR)。这下终究好啦,全球任何一个区域的软件,能够不必修正地就可以在另外一个区域运转了。固然我用IE扫瞄日本网站,显现出我不熟悉的日文笔墨,但最少不会是乱码了。UNICODE的局限是0x0000-0xFFFF共6万多个字符,个中光汉字就占用了4万多个。嘿嘿,中国人赚年夜发了:0)
  在程序中利用各类字符集的办法:
constchar*p="Hello";//利用ASCII字符集constchar*p="你好";//利用MBCS字符集,因为MBCS完整兼容ASCII,多半情形下,我们其实不严厉辨别他们LPCSTRp="Hello,你好";//意义同上constWCHAR*p=L"Hello,你好";//利用UNICODE字符集LPCOLESTRp=L"Hello,你好";//意义同上//假如预界说了_UNICODE,则暗示利用UNICODE字符集;假如界说了_MBCS,则暗示利用MBCSconstTCHAR*p=_T("Hello,你好");LPCTSTRp=_T("Hello,你好");//意义同上  在下面的例子中,T长短常成心思的一个标记(TCHAR、LPCTSTR、LPTSTR、_T()、_TEXT()...),它暗示利用一种两头范例,既不明白暗示利用MBCS,也不明白暗示利用UNICODE。那究竟利用哪一种字符集那?嘿嘿......编译的时分决意吧。设置前提编译的体例是:VC6中,"ProjectSettings...C/C++卡片Preprocessordefinitions"中增加或修正_MBCS、_UNICODE;VC.NET中,"项目属性设置属性惯例字符集"然后用组合窗举行选择。利用T范例,长短常好的习气,严峻保举!

4、BSTR
  COM中除利用一些复杂尺度的数据范例外(注2),字符串范例必要出格重点地申明一下。还记得准绳吗?COM组件是运转在散布式情况中的。普通地说,你不克不及间接把一个内存指针间接作为参数传送给COM函数。你想一想,体系必要把这块内存的内容传送到“地球另外一边”的盘算机上,因而,我最少必要晓得你这块内存的尺寸吧?否则让我怎样传送呀?传送几字节呀?!而字符串又长短经常用的一品种型,因而COM计划者引进了BASIC中字符串范例的暗示体例---BSTR。BSTR实际上是一个指针范例,它的内存布局是:(输出程序片断BSTRp=::SysAllocString(L"Hello,你好");断点实行,然后察看p的内存)


<br>
、BSTR内存布局

  BSTR是一个指向UNICODE字符串的指针,且BSTR向前的4个字节中,利用DWORD保留着这个字符串的字节长度(没有含字符串的停止符)。因而体系就可以够准确处置并传送这个字符串到“地球另外一边”了。出格必要注重的是,因为BSTR的指针就是指向UNICODE串,因而BSTR和LPOLESTR能够在必定水平上混用,但必定要注重:
  有函数fun(LPCOLESTRlp),则你挪用BSTRp=...;fun(p);准确
  有函数fun(constBSTRbstr),则你挪用LPCOLESTRp=...;fun(p);毛病!!!
有关BSTR的处置函数:
 API函数申明SysAllocString()请求一个BSTR指针,并初始化为一个字符串SysFreeString()开释BSTR内存SysAllocStringLen()请求一个指定字符长度的BSTR指针,并初始化为一个字符串SysAllocStringByteLen()请求一个指定字节长度的BSTR指针,并初始化为一个字符串SysReAllocStringLen()从头请求BSTR指针CString函数
申明
AllocSysString()从CString失掉BSTRSetSysString()从头请求BSTR指针,并复制到CString中CComBSTR函数
ATL的BSTR包装类。在atlbase.h中界说
Append()、AppendBSTR()、AppendBytes()、ArrayToBSTR()、BSTRToArray()、AssignBSTR()、Attach()、Detach()、Copy()、CopyTo()、Empty()、Length()、ByteLength()、ReadFromStream()、WriteToStream()、LoadString()、ToLower()、ToUpper()
运算符重载:!,!=,==,<,>,&,+=,+,=,BSTR太多了,但从函数称号不克不及看出其基础功效。具体材料,检察MSDN吧。别的,左边函数,有良多是ATL7.0供应的,VC6.0下所带的ATL3.0不撑持。
因为我们未来次要用ATL开辟组件程序,因而利用ATL的CComBSTR为主。VC也供应了别的的包装类_bstr_t。
5、各类字符串范例之间的转换
  1、函数WideCharToMultiByte(),转换UNICODE到MBCS。利用典范:
LPCOLESTRlpw=L"Hello,你好";size_twLen=wcslen(lpw)+1;//宽字符字符长度,+1暗示包括字符串停止符intaLen=WideCharToMultiByte(//第一次挪用,盘算所需MBCS字符串字节长度CP_ACP,0,lpw,//宽字符串指针wLen,//字符长度NULL,0,//参数0暗示盘算转换后的字符空间NULL,NULL);LPSTRlpa=newchar;WideCharToMultiByte(CP_ACP,0,lpw,wLen,lpa,//转换后的字符串指针aLen,//给出空间巨细NULL,NULL);//此时,lpa中保留着转换后的MBCS字符串............delete[]lpa;
2、函数MultiByteToWideChar(),转换MBCS到UNICODE。利用典范:LPCSTRlpa="Hello,你好";size_taLen=strlen(lpa)+1;intwLen=MultiByteToWideChar(CP_ACP,0,lpa,aLen,NULL,0);LPOLESTRlpw=newWCHAR;MultiByteToWideChar(CP_ACP,0,lpa,aLen,lpw,wLen);............delete[]lpw;
3、利用ATL供应的转换宏。
 
A2BSTROLE2AT2AW2AA2COLEOLE2BSTRT2BSTRW2BSTRA2CTOLE2CAT2CAW2CAA2CWOLE2CTT2COLEW2COLEA2OLEOLE2CWT2CWW2CTA2TOLE2TT2OLEW2OLEA2WOLE2WT2WW2T
上表中的宏函数,实在十分简单影象:2好弄笑的缩写,to的发音和2一样,以是借用来暗示“转换为、转换到”的寄义。AANSI字符串,也就是MBCS。W、OLE宽字符串,也就是UNICODE。T两头范例T。假如界说了_UNICODE,则T暗示W;假如界说了_MBCS,则T暗示ACconst的缩写利用典范:
#include<atlconv.h>voidfun(){USES_CONVERSION;//只必要挪用一次,就能够在函数中举行屡次转换LPCTSTRlp=OLE2CT(L"Hello,你好"));............//不必显式开释lp的内存,由于//因为ATL转换宏利用栈作为一时空间,函数停止后会主动开释栈空间。}  利用ATL转换宏,因为不必开释一时空间,以是利用起来十分便利。可是思索到栈空间的尺寸(VC默许2M),利用时要注重几点:
1、只合适于举行短字符串的转换;
2、不要试图在一个次数对照多的轮回体内举行转换;
3、不要试图对字符型文件内容举行转换,由于文件尺寸一样平常情形下是对照年夜的;
4、对情形2和3,要利用MultiByteToWideChar()和WideCharToMultiByte();

6、VARIANT
  C++、BASIC、Java、Pascal、Script......盘算机言语多种多样,而它们各自又都有本人的数据范例,COM发生目标,个中之一就是要跨言语(注3)。而VARIANT数据范例就具有跨言语的特征,同时它能够暗示(存储)恣意范例的数据。从C言语的角度来说,VARIANT实际上是一个布局,布局顶用一个域(vt)暗示------该变量究竟暗示的是甚么范例数据,同时真实的数据则存贮在union空间中。布局的界说太长了(固然长,但实在很复杂)人人往看MSDN的形貌吧,这里给出怎样利用的复杂示例:

先生:我想用VARIANT暗示一个4字节长的整数,怎样做?
先生:VARIANTv;v.vt=VT_I4;v.lVal=100;

先生:我想用VARIANT暗示布尔值“真”,怎样做?
先生:VARIANTv;v.vt=VT_BOOL;v.boolVal=VARIANT_TRUE;
先生:这么贫苦?我能不克不及v.boolVal=true;如许写?
先生:不成以!由于
 范例字节长度假值真值bool1(char)0(false)1(true)BOOL4(int)0(FALSE)1(TRUE)VT_BOOL2(shortint)0(VARIANT_FALSE)-1(VARIANT_TRUE)  以是假如你v.boolVal=true如许赋值,那末未来if(VARIANT_TRUE==v.boolVal)的时分会出成绩(-1!=1)。可是你注重察看,任何布尔范例的“假”都是0,因而作为一个好习气,在做布尔判别的时分,不要和“真值”比拟较,而要与“假值”做对照。
先生:感谢先生,你太牛了。我对先生的仰慕如滚滚江水,绵延不停......

先生:我想用VARIANT保留字符串,怎样做?
先生:VARIANTv;v.vt=VT_BSTR;v.bstrVal=SysAllocString(L"Hello,你好");

先生:哦......我分明了。但是这么操纵真够贫苦的,有无复杂一些的办法?
先生:有呀,你可使用现成的包装类CComVariant、COleVariant、_variant_t。好比下面三个成绩就能够如许誊写:CComVariantv1(100),v2(true),v3("Hello,你好");复杂了吧?!(注4)

先生:先生,我再问最初一个成绩,我怎样用VARIANT保留一个数组?
先生:这个成绩很庞大,我如今不克不及告知你,我如今告知你怕你印象不深......(注5)
先生:~!@#$%^&*()......晕!

7、小结
以上所先容的内容,是基础功,必需纯熟把握。先到这里吧,歇息一会儿......更多出色内容,敬请存眷《COM组件计划与使用(四)》


注1:在后续的ISupportErrorInfo接口中先容。
注2:罕见的数据范例,请参考IDL文件的申明。(别发急,还没写那......嘿嘿)
注3:跨言语就是各类言语中都能利用COM组件。但啥时分能跨平台呢?
注4:CComVariant/COlevariant/_variant_t请参看MSDN。
注5:关于平安数组SafeArray的利用,在后续的文章中会商。
原文链接:http://www.vckbase.com/document/viewdoc/?id=1488

还得说上一点,就java本质而言,是面相对象的,但是你有没有发现,java也不全是,比如说基本类型,int,那他就是整型而不是对象,转换类型是还得借助包装类。

活着的死人 发表于 2015-1-21 11:10:49

Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。

小女巫 发表于 2015-1-30 07:14:44

学Java必读的两个开源程序就是Jive和Pet Store.。 Jive是国外一个非常著名的BBS程序,完全开放源码。论坛的设计采用了很多先进的技术,如Cache、用户认证、Filter、XML等,而且论坛完全屏蔽了对数据库的访问,可以很轻易的在不同数据库中移植。论坛还有方便的安装和管理程序,这是我们平时编程时容易忽略的一部份(中国程序员一般只注重编程的技术含量,却完全不考虑用户的感受,这就是我们与国外软件的差距所在)。

灵魂腐蚀 发表于 2015-2-6 07:54:31

是一种将安全性(Security)列为第一优先考虑的语言

蒙在股里 发表于 2015-2-15 17:54:59

一般学编程语言都是从C语开始学的,我也不例外,但还是可能不学过程语言而直接学面向对象语言的,你是刚接触语言,还是从C开始学比较好,基础会很深点,如果你直接学习JAVA也能上手,一般大家在学语言的时候都记一些语言的关键词,常有的包和接口等。再去做逻辑代码的编写,以后的学习过程都是从逻辑代码编写中提升的,所以这方面都是经验积累的。你要开始学习就从

乐观 发表于 2015-2-20 09:18:45

应用在电视机、电话、闹钟、烤面包机等家用电器的控制和通信。由于这些智能化家电的市场需求没有预期的高,Sun公司放弃了该项计划。随着1990年代互联网的发展

分手快乐 发表于 2015-3-5 20:49:11

还好,SUN提供了Javabean可以把你的JSP中的 Java代码封装起来,便于调用也便于重用。

爱飞 发表于 2015-3-5 23:34:22

是一种由美国SUN计算机公司(Sun Microsystems, Inc.)所研究而成的语言

再见西城 发表于 2015-3-9 23:55:17

你就该学一学Servlet了。Servlet就是服务器端小程序,他负责生成发送给客户端的HTML文件。JSP在执行时,也是先转换成Servlet再运行的。虽说JSP理论上可以完全取代Servlet,这也是SUN推出JSP的本意,可是Servlet用来控制流程跳转还是挺方便的,也令程序更清晰。接下来你应该学习一下Javabean了,可能你早就看不管JSP在HTML中嵌Java代码的混乱方式了,这种方式跟ASP又有什么区别呢?

谁可相欹 发表于 2015-3-12 09:58:13

任职于太阳微系统的詹姆斯·高斯林等人于1990年代初开发Java语言的雏形,最初被命名为Oak,目标设置在家用电器等小型系统的程序语言

精灵巫婆 发表于 2015-3-19 19:49:17

当然你也可以参加一些开源项目,一方面可以提高自己,另一方面也是为中国软件事业做贡献嘛!开发者在互联网上用CVS合作开发,用QQ,MSN,E-mail讨论联系,天南海北的程序员分散在各地却同时开发同一个软件,是不是很有意思呢?

若天明 发表于 2015-3-31 06:52:50

Java 编程语言的风格十分接近C、C++语言。

不帅 发表于 2015-4-1 01:08:31

任职于太阳微系统的詹姆斯·高斯林等人于1990年代初开发Java语言的雏形,最初被命名为Oak,目标设置在家用电器等小型系统的程序语言

仓酷云 发表于 2015-4-1 07:08:35

http://www.jdon.com/去下载,或到同济技术论坛的服务器ftp://nro.shtdu.edu.cn去下,安装上有什么问题,可以到论坛上去提问。

因胸联盟 发表于 2015-4-26 01:10:28

一般学编程语言都是从C语开始学的,我也不例外,但还是可能不学过程语言而直接学面向对象语言的,你是刚接触语言,还是从C开始学比较好,基础会很深点,如果你直接学习JAVA也能上手,一般大家在学语言的时候都记一些语言的关键词,常有的包和接口等。再去做逻辑代码的编写,以后的学习过程都是从逻辑代码编写中提升的,所以这方面都是经验积累的。你要开始学习就从

深爱那片海 发表于 2015-4-26 06:11:41

一直感觉JAVA很大,很杂,找不到学习方向,前两天在网上找到了这篇文章,感觉不错,给没有方向的我指了一个方向,先不管对不对,做下来再说。

冷月葬花魂 发表于 2015-4-28 23:09:34

Java 不同于一般的编译执行计算机语言和解释执行计算机语言。它首先将源代码编译成二进制字节码(bytecode),然后依赖各种不同平台上的虚拟机来解释执行字节码。从而实现了“一次编译、到处执行”的跨平台特性。

金色的骷髅 发表于 2015-7-15 21:49:37

一直感觉JAVA很大,很杂,找不到学习方向,前两天在网上找到了这篇文章,感觉不错,给没有方向的我指了一个方向,先不管对不对,做下来再说。

若相依 发表于 2015-7-20 13:29:55

自从Sun推出Java以来,就力图使之无所不包,所以Java发展到现在,按应用来分主要分为三大块:J2SE,J2ME和J2EE,这也就是Sun ONE(Open Net Environment)体系。J2SE就是Java2的标准版,主要用于桌面应用软件的编程;J2ME主要应用于嵌入是系统开发,如手机和PDA的编程;J2EE是Java2的企业版,主要用于分布式的网络程序的开发,如电子商务网站和ERP系统。

山那边是海 发表于 2015-7-29 09:06:07

其实说这种话的人就如当年小日本号称“三个月拿下中国”一样大言不惭。不是Tomjava泼你冷水,你现在只是学到了Java的骨架,却还没有学到Java的精髓。接下来你得研究设计模式了。
页: [1]
查看完整版本: JAVA网页编程之COM组件计划与使用(三)数据范例仓酷云