返回介绍

A.3 J/Direct

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

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 技术交流群。

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

发布评论

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