返回介绍

A.5.4 用 Java 设计 COM 客户

发布于 2024-10-15 23:56:38 字数 2421 浏览 0 评论 0 收藏 0

现在,让我们转到另一侧,并用 Java 开发一个 COM 客户。这个程序会调用系统已安装的 COM 服务器内的服务。就目前这个例子来说,我们使用的是在前一个例子里为服务器实现的一个客户。尽管代码在 Java 程序员的眼中看起来比较熟悉,但在幕后发生的一切却并不寻常。本例使用了用 Java 写成的一个服务器,但它可应用于系统内安装的任何 ActiveX 控件、ActiveX Automation 服务器或者 ActiveX 组件——只要我们有一个类型库。

首先,我们将 Jactivex 工具应用于服务器的类型库。Jactivex 有一系列选项和开关可供选择。但它最基本的形式是读取一个类型库,并生成 Java 源文件。这个源文件保存于我们的 windows/java/trustlib 目录中。通过下面这行代码,它应用于为外部 COM Automation 服务器生成的类型库:

jactivex /javatlb JavaAdder.tlb

Jactivex 完成以后,我们再来看看自己的 windows/java/trustlib 目录。此时可在其中看到一个新的子目录,名为 javaadder。这个目录包含了用于新包的源文件。这是在 Java 里与类型库的功能差不多的一个库。这些文件需要使用 Microsoft 编译器的专用引导命令:@com。jactivex 生成多个文件的原因是 COM 使用多个实体来描述一个 COM 服务器(另一个原因是我没有对 MIDL 文件和 Java/COM 工具的使用进行细致的调整)。

名为 Adder.java 的文件等价于 MIDL 文件中的一个 coclass 引导命令:它是对一个 COM 类的声明。其他文件则是由服务器揭示出来的 COM 接口的 Java 等价物。这些接口(比如 Adder_DispatchDefault.java)都属于“遣送”(Dispatch)接口,属于 Automation 控制器与 Automation 服务器之间的沟通机制的一部分。Java/COM 集成特性也支持双接口的实现与使用。但是,IDispatch 和双接口的问题已超出了本附录的范围。

在下面,大家可看到对应的客户代码。第一行只是导入由 jactivex 生成的包。然后创建并使用 COM Automation 服务器的一个实例,就象它是一个原始的 Java 类那样。请注意行内的类型模型,其中“例示”了 COM 对象(即生成并调用它的一个实例)。这与 COM 对象模型是一致的。在 COM 中,程序员永远不会得到对整个对象的一个引用。相反,他们只能拥有对类内实现的一个或多个接口的引用。

“例示”Adder 类的一个 Java 对象以后,就相当于指示 COM 激活服务器,并创建这个 COM 对象的一个实例。但我们随后必须指定自己想使用哪个接口,在由服务器实现的接口中挑选一个。这正是类型模型完成的工作。这儿使用的是“默认遣送”接口,它是 Automation 控制器用于同一个 Automation 服务器通信的标准接口。欲了解这方面的细节,请参考由 Ibid 编著的《Inside COM》。请注意激活服务器并选择一个 COM 接口是多么容易!

import javaadder.*;

public class JavaClient {
  public static void main(String [] args) {
    Adder_DispatchDefault iAdder =
         (Adder_DispatchDefault) new Adder();
    iAdder.setAddend(3);
    iAdder.sum();
    iAdder.sum();
    iAdder.sum();
    System.out.println(iAdder.getResult());
  }
}

现在,我们可以编译它,并开始运行程序。

1. com.ms.com 包

com.ms.com 包为 COM 的开发定义了数量众多的类。它支持 GUID 的使用——Variant(变体)和 SafeArray Automation(安全数组自动)类型——能与 ActiveX 控件在一个较深的层次打交道,并可控制 COM 异常。

由于篇幅有限,这里不可能涉及所有这些主题。但我想着重强调一下 COM 异常的问题。根据规范,几乎所有 COM 函数都会返回一个 HRESULT 值,它告诉我们函数调用是否成功,以及失败的原因。但若观察服务器和客户代码中的 Java 方法签名,就会发现没有 HRESULT。相反,我们用函数返回值从一些函数那里取回数据。“虚拟机”(VM)会将 Java 风格的函数调用转换成 COM 风格的函数调用,甚至包括返回参数。但假若我们在服务器里调用的一个函数在 COM 这一级失败,又会在虚拟机里出现什么事情呢?在这种情况下,JVM 会认为 HRESULT 值标志着一次失败,并会产生类 com.ms.com.ComFailException 的一个固有 Java 异常。这样一来,我们就可用 Java 异常控制机制来管理 COM 错误,而不是检查函数的返回值。

如欲深入了解这个包内包含的类,请参考微软公司的产品文档。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文