。HRESULT代表一个包含了三个字段的整数。这样便可使用多个失败和成功代码,同时还可以使用其他信息。由于COM函数返回的是一个HRESULT,所以不能用返回值从函数调用里取回原始数据。若必须返回数据,可传递指向一个内存区域的指针,函数将在那个区域里填充数据。我们把这称为“外部参数”。作为Java/COM程序员,我们不必过于关注这个问题,因为虚拟机会帮助我们自动照管一切。这个问题将在后续的小节里讲述。
A.5.2 MS Java/COM集成
同C++/COM程序员相比,Microsoft Java编译器、虚拟机以及各式各样的工具极大简化了
Java/COM程序员的
工作。编译器有特殊的引导命令和包,可将Java类当作COM类对待。但在大多数情况下,我们只需依赖Microsoft JVM为COM提供的支持,同时利用两个有力的外部工具。
Microsoft Java Virtual Machine(JVM)在COM和Java对象之间扮演了一座桥梁的角色。若将Java对象创建成一个COM服务器,那么我们的对象仍然会在JVM内部运行。Microsoft JVM是作为一个DLL实现的,它向操作系统展示出了COM接口。在内部,JVM将对这些COM接口的函数调用映射成Java对象中的方法调用。当然,JVM必须知道哪个Java类文件对应于服务器执行模块;之所以能够找出这方面的信息,是由于我们事前已用Javareg在Windows注册表内注册了类文件。Javareg是与Microsoft Java SDK配套提供的一个工具程序,能读入一个Java类文件,生成相应的类型库以及一个GUID,并可将类注册到系统内。亦可用Javareg注册远程服务器。例如,可用它注册在不同机器上运行的一个服务器。
如果想写一个Java/COM客户,必须经历一系列不同的步骤。Java/COM“客户”是一些特殊的Java代码,它们想激活和使用系统内注册的一个COM服务器。同样地,虚拟机会与COM服务器沟通,并将它提供的服务作为Java类内的各种方法展示(揭示)出来。另一个Microsoft工具是jactivex,它能读取一个类型库,并生成相应的Java源文件,在其中包含特殊的编译器引导命令。生成的源文件属于我们在指
定类型库之后命名的一个包的一部分。下一步是在自己的COM客户Java源文件中导入那个包。
接下来让我们讨论两个例子。
A.5.3 用Java
设计COM服务器
本节将介绍ActiveX控件、Automation服务器或者其他任何符合COM规范的服务器的开发过程。下面这个例子实现了一个简单的Automation服务器,它能执行整数加法。我们用setAddend()方法设置addend的值。每次调用sum()方法的时候,addend就会添加到当前result里。我们用getResult()获得result值,并用clear()重新设置值。用于实现这一行为的Java类是非常简单的:
1023页上程序
为了将这个Java类作为一个COM对象使用,我们将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复制到Windows\Java\trustlib目录。考虑到安全方面的原因(特别是涉及程序片调用COM服务的问题),只有在COM服务器已安装到trustlib目录的前提下,这些服务器才会被激活。
现在,我们已在