友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
一世书城 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

Java编程思想第4版[中文版](PDF格式)-第212章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




位服务器代码,激活对象,同它建立链接,然后使用它。以后,我们可安装控件的新版本,我们的应用程序 

应该仍然能够运行;即使在最糟的情况下,它也应礼貌地报告一条出错消息,比如“控件未找到”等等;一 

般不会莫名其妙地挂起或死机。  

在这些情况下,我们的组件是在独立的可执行代码文件里实现的:DLL 或 EXE。若服务器对象在一个独立的可 

执行代码文件里实现,就需要由操作系统提供的一个标准方法,从而激活这些对象。当然,我们并不想在自 

己的代码里使用DLL 或 EXE 的物理名称及位置,因为这些参数可能经常发生变化。此时,我们想使用的是由 

操作系统维护的一些标识符。另外,我们的应用程序需要对服务器展示出来的服务进行的一个描述。下面这 

两个小节将分别讨论这两个问题。  

  

1。 GUID和注册表  

 采用结构化的整数值(长度为 128位)唯一性地标识系统中注册的 项目。这些数字的正式名称叫作 

GUID (Globally Unique IDentifier,全局唯一标识符),可由特殊的工具生成。此外,这些数字可以保证 

在“任何空间和时间”里独一无二,没有重复。在空间,是由于数字生成器会读取网卡的 ID号码;在时间, 

是由于同时会用到系统的日期和时间。可用GUID 标识 类(此时叫作 CLSID)或者 接口(IID)。尽 

管名字不同,但基本概念与二进制结构都是相同的。GUID 亦可在其他环境中使用,这里不再赘述。  

GUID 以及相关的信息都保存在Windows 注册表中,或者说保存在“注册数据库”(Registration  

Database )中。这是一种分级式的数据库,内建于操作系统中,容纳了与系统软硬件配置有关的大量信息。 

对于,注册表会跟踪系统内安装的组件,比如它们的CLSID、实现它们的可执行文件的名字及位置以及其 

他大量细节。其中一个比较重要的细节是组件的ProgID;ProgID 在概念上类似于GUID,因为它们都标识着 

一个 组件。区别在于 GUID 是一个二进制的、通过算法生成的值。而 ProgID 则是由程序员定义的字串 

值。ProgID 是随同一个CLSID 分配的。  

我们说一个  组件已在系统内注册,最起码的一个条件就是它的 CLSID 和它的执行文件已存在于注册表中 



                                                                662 


…………………………………………………………Page 664……………………………………………………………

 (ProgID 通常也已就位)。在后面的例子里,我们主要任务就是注册与使用 组件。  

注册表的一项重要特点就是它作为客户和服务器对象之间的一个去耦层使用。利用注册表内保存的一些信 

息,客户会激活服务器;其中一项信息是服务器执行模块的物理位置。若这个位置发生了变动,注册表内的 

信息就会相应地更新。但这个更新过程对于客户来说是“透明”或者看不见的。后者只需直接使用ProgID 或 

CLSID 即可。换句话说,注册表使服务器代码的位置透明成为了可能。随着D (分布式)的引入,在 

本地机器上运行的一个服务器甚至可移到网络中的一台远程机器,整个过程甚至不会引起客户对它的丝毫注 

意(大多数情况下如此)。  

  

2。 类型库  

由于 具有动态链接的能力,同时由于客户和服务器代码可以分开独立发展,所以客户随时都要动态侦测 

由服务器展示出来的服务。这些服务是用“类型库”(Type Library)中一种二进制的、与语言无关的形式 

描述的(就象接口和方法签名)。它既可以是一个独立的文件(通常采用。TLB 扩展名),也可以是链接到执 

行程序内部的一种Win32 资源。运行期间,客户会利用类型库的信息调用服务器中的函数。  

我们可以写一个Microsoft Interface Definition Language (微软接口定义语言,MIDL )源文件,用MIDL 

编译器编译它,从而生成一个。TLB 文件。MIDL 语言的作用是对 类、接口以及方法进行描述。它在名称、 

语法以及用途上都类似 OMB/CORBA IDL 。然而,Java 程序员不必使用MIDL 。后面还会讲到另一种不同的 

Microsoft 工具,它能读入Java 类文件,并能生成一个类型库。  

  

3。 :HRESULT 中的函数返回代码  

由服务器展示出来的 函数会返回一个值,采用预先定义好的HRESULT 类型。HRESULT 代表一个包含了三 

个字段的整数。这样便可使用多个失败和成功代码,同时还可以使用其他信息。由于  函数返回的是一个 

HRESULT,所以不能用返回值从函数调用里取回原始数据。若必须返回数据,可传递指向一个内存区域的指 

针,函数将在那个区域里填充数据。我们把这称为 “外部参数”。作为Java/ 程序员,我们不必过于关注 

这个问题,因为虚拟机会帮助我们自动照管一切。这个问题将在后续的小节里讲述。  



A。5。2 MS Java/ 集成  



同C++/ 程序员相比,Microsoft Java 编译器、虚拟机以及各式各样的工具极大简化了Java/ 程序员 

的工作。编译器有特殊的引导命令和包,可将 Java 类当作  类对待。但在大多数情况下,我们只需依赖 

Microsoft JVM 为 提供的支持,同时利用两个有力的外部工具。  

Microsoft Java Virtual Machine (JVM)在 和Java 对象之间扮演了一座桥梁的角色。若将Java 对象创 

建成一个 服务器,那么我们的对象仍然会在 JVM 内部运行。Microsoft JVM 是作为一个 DLL 实现的,它 

向操作系统展示出了 接口。在内部,JVM 将对这些 接口的函数调用映射成 Java 对象中的方法调用。 

当然,JVM 必须知道哪个Java 类文件对应于服务器执行模块;之所以能够找出这方面的信息,是由于我们事 

前已用Javareg 在Windows 注册表内注册了类文件。Javareg 是与Microsoft Java SDK 配套提供的一个工具 

程序,能读入一个 Java 类文件,生成相应的类型库以及一个 GUID,并可将类注册到系统内。亦可用 Javareg 

注册远程服务器。例如,可用它注册在不同机器上运行的一个服务器。  

如果想写一个Java/ 客户,必须经历一系列不同的步骤。Java/ “客户”是一些特殊的Java 代码,它 

们想激活和使用系统内注册的一个  服务器。同样地,虚拟机会与  服务器沟通,并将它提供的服务作 

为Java 类内的各种方法展示(揭示)出来。另一个Microsoft 工具是 jactivex,它能读取一个类型库,并 

生成相应的 Java 源文件,在其中包含特殊的编译器引导命令。生成的源文件属于我们在指定类型库之后命名 

的一个包的一部分。下一步是在自己的 客户Java 源文件中导入那个包。  

接下来让我们讨论两个例子。  



A。5。3  用 Java 设计  服务器  



本节将介绍 ActiveX 控件、Automation 服务器或者其他任何符合 规范的服务器的开发过程。下面这个例 

子实现了一个简单的Automation 服务器,它能执行整数加法。我们用 setAddend()方法设置addend 的值。 

每次调用 sum()方法的时候,addend 就会添加到当前result 里。我们用 getResult()获得result 值,并用 

clear()重新设置值。用于实现这一行为的 Java 类是非常简单的:  

  

public class Adder {  

  private int addend;  



                                                                      663 


…………………………………………………………Page 665……………………………………………………………

  private int result;  

  public void setAddend(int a) { addend = a; }  

  public int getAddend() { return addend; }  

  public int getResult() { return result; }  

  public void sum() { result += addend;  }  

  public void clear() {  

    result = 0;  

    addend = 0;  

  }  

}  

  

为了将这个 Java 类作为一个  对象使用,我们将 Javareg 工具应用于编译好的Adder。class 文件。这个工 

具提供了一系列选项;在这种情况下,我们指定Java 类文件名(〃Adder〃),想为这个服务器在注册表里置 

入的ProgID (〃JavaAdder。Adder。1〃 ),以及想为即将生成的类型库指定的名字(〃JavaAdder。tlb〃)。由于 

尚未给出CLSID,所以 Javareg 会自动生成一个。若我们再次对同样的服务器调用 Javareg,就会直接使用现 

成的CLSID。  

  

javareg /register  

/class:Adder /progid:JavaAdder。Adder。1  

/typelib:JavaAdder。tlb  

  

Javareg 也会将新服务器注册到 Windows 注册表。此时,我们必须记住将 Adder。class 复制到 

WindowsJavatrustlib 目录。考虑到安全方面的原因(特别是涉及程序片调用 服务的问题),只有在 

 服务器已安装到trustlib 目录的前提下,这些服务器才会被激活。  

现在,我们已在自己的系统中安装了一个新的 Automation 服务器。为进行测试,我们需要一个 Automation 

控制器,而 Automation 控制器就是 Visual Basic (VB )。在下面,大家会看到几行VB 代码。按照 VB 的格 

式,我设置了一个文本框,用它从用户那里接收要相加的值。并用一个标签显示结果,用两个下推按钮分别 

调用 sum()和 clear()方法。最开始,我们声明了一个名为Adder 的对象变量。在Form_Load 子例程中(在窗 

体首次显示时载入),会调用Adder 自动服务器的一个新实例,并对窗体的文本字段进行初始化。一旦用户 

按下“Sum”或者“Clear”按钮,就会调用服务器中对应的方法。  

  

Dim Adder As Object  

  

Private Sub Form_Load()  

    Set Adder = CreateObject(〃JavaAdder。Adder。1〃)  

    Addend。Text = Adder。getAddend  

    Result。Caption = Adder。getResult  

End Sub  

  

Private Sub SumBtn_Click()  

    Adder。setAddend (Addend。Text)  

    Adder。Sum  

    Result。Caption = Adder。getResult  

End Sub  

  

Private Sub ClearBtn_Click()  

    Adder。Clear  

    Addend。Text = Adder。getAddend  

    Result。Caption = Adder。getResult  

End Sub  

  

注意,这段代码根本不知道服务器是用Java 实现的。  



                                                                                             664 


…………………………………………………………Page 666……………………………………………………………

运行这个程序并调用了 CreateObject()函数以后,就�
返回目录 上一页 下一页 回到顶部 赞(0) 踩(0)
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!