- 写在前面的话
- 引言
- 第 1 章 对象入门
- 第 2 章 一切都是对象
- 第 3 章 控制程序流程
- 第 4 章 初始化和清除
- 第 5 章 隐藏实施过程
- 第 6 章 类再生
- 第 7 章 多形性
- 第 8 章 对象的容纳
- 第 9 章 违例差错控制
- 第 10 章 Java IO 系统
- 第 11 章 运行期类型鉴定
- 第 12 章 传递和返回对象
- 第 十三 章 创建窗口和程序片
- 第 14 章 多线程
- 第 15 章 网络编程
- 第 16 章 设计范式
- 第 17 章 项目
- 附录 A 使用非 JAVA 代码
- 附录 B 对比 C++和 Java
- 附录 C Java 编程规则
- 附录 D 性能
- 附录 E 关于垃圾收集的一些话
- 附录 F 推荐读物
A.3 J/Direct
J/Direct 是调用 Win32 DLL 函数最简单的方式。它的主要设计目标是与 Win32API 打交道,但完全可用它调用其他任何 API。但是,尽管这一特性非常方便,但它同时也造成了某些限制,且降低了性能(与 RNI 相比)。但 J/Direct 也有一些明显的优点。首先,除希望调用的那个 DLL 里的代码之外,没有必要再编写额外的非 Java 代码,换言之,我们不需要一个封装器或者代理/存根 DLL。其次,函数自变量与标准数据类型之间实现了自动转换。若必须传递用户自定义的数据类型,那么 J/Direct 可能不按我们的希望工作。第三,就象下例展示的那样,它非常简单和直接。只需少数几行,这个例子便能调用 Win32 API 函数 MessageBox(),它能弹出一个小的模态窗口,并带有一个标题、一条消息、一个可选的图标以及几个按钮。
public class ShowMsgBox { public static void main(String args[]) throws UnsatisfiedLinkError { MessageBox(0, "Created by the MessageBox() Win32 func", "Thinking in Java", 0); } /** @dll.import("USER32") */ private static native int MessageBox(int hwndOwner, String text, String title, int fuStyle); }
令人震惊的是,这里便是我们利用 J/Direct 调用 Win32 DLL 函数所需的全部代码。其中的关键是位于示范代码底部的 MessageBox() 声明之前的 @dll.import 引导命令。它表面上看是一条注释,但实际并非如此。它的作用是告诉编译器:引导命令下面的函数是在 USER32 DLL 里实现的,而且应相应地调用。我们要做的全部事情就是提供与 DLL 内实现的函数相符的一个原型,并调用函数。但是毋需在 Java 版本里手工键入需要的每一个 Win32 API 函数,一个 Microsoft Java 包会帮我们做这件事情(很快就会详细解释)。为了让这个例子正常工作,函数必须“按名称”由 DLL 导出。但是,也可以用 @dll.import 引导命令“按顺序”链接。举个例子来说,我们可指定函数在 DLL 里的入口位置。稍后还会具体讲述 @dll.import 引导命令的特性。
用非 Java 代码进行链接的一个重要问题就是函数参数的自动配置。正如大家看到的那样,MessageBox() 的 Java 声明采用了两个字串自变量,但原来的 C 方案则采用了两个 char 指针。编译器会帮助我们自动转换标准数据类型,同时遵照本章后一节要讲述的规则。
最好,大家或许已注意到了 main() 声明中的 UnsatisfiedLinkError 异常。在运行期的时候,一旦链接程序不能从非 Java 函数里解析出符号,就会触发这一异常(事件)。这可能是由多方面的原因造成的:.dll 文件未找到;不是一个有效的 DLL;或者 J/Direct 未获您所使用的虚拟机的支持。为了使 DLL 能被找到,它必须位于 Windows 或 Windows\System 目录下,位于由 PATH 环境变量列出的一个目录中,或者位于和.class 文件相同的目录。J/Direct 获得了 Microsoft Java 编译器 1.02.4213 版本及更高版本的支持,也获得了 Microsoft JVM 4.79.2164 及更高版本的支持。为了解自己编译器的版本号,请在命令行下运行 JVC,不要加任何参数。为了解 JVM 的版本号,请找到 msjava.dll 的图标,并利用右键弹出菜单观察它的属性。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论