代码。
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);
}
655
…………………………………………………………Page 657……………………………………………………………
/** @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 或WindowsSystem 目录下,位于由PATH 环境变量列出的一个目录中,或者位于和。class 文
件相同的目录。J/Direct 获得了 Microsoft Java 编译器 1。02。4213 版本及更高版本的支持,也获得了
Microsoft JVM 4。79。2164 及更高版本的支持。为了解自己编译器的版本号,请在命令行下运行 JVC,不要加
任何参数。为了解 JVM 的版本号,请找到msjava。dll 的图标,并利用右键弹出菜单观察它的属性。
A。3。1 @dll。import 引导命令
作为使用J/Direct 唯一的途径,@dll。import 引导命令相当灵活。它提供了为数众多的修改符,可用它们自
定义同非Java 代码建立链接关系的方式。它亦可应用于类内的一些方法,或应用于整个类。也就是说,我们
在那个类内声明的所有方法都是在相同的 DLL 里实现的。下面让我们具体研究一下这些特性。
1。 别名处理和按顺序链接
为了使@dll。import 引导命令能象上面显示的那样工作,DLL 内的函数必须按名字导出。然而,我们有时想使
用与DLL 里原始名字不同的一个名字(别名处理),否则函数就可能按编号(比如按顺序)导出,而不是按
名字导出。下面这个例子声明了FinestraDiMessaggio() (用意大利语说的“MessageBox”)。正如大家看
到的那样,使用的语法是非常简单的。
public class Aliasing {
public static void main(String args'')
throws UnsatisfiedLinkError {
FinestraDiMessaggio(0;
〃Created by the MessageBox() Win32 func〃;
〃Thinking in Java〃; 0);
}
/** @dll。import(〃USER32〃;
entrypoint=〃MessageBox〃) */
private static native int
FinestraDiMessaggio(int hwndOwner; String text;
String title; int fuStyle);
}
下面这个例子展示了如何同DLL 里并非按名字导出的一个函数建立链接,那个函数事实是按它们在DLL 里的
位置导出的。这个例子假设有一个名为MYMATH 的DLL,这个 DLL 在位置编号 3 处包含了一个函数。那个函数
获取两个整数作为自变量,并返回两个整数的和。
656
…………………………………………………………Page 658……………………………………………………………
public class ByOrdinal {
public static void main(String args'')
throws UnsatisfiedLinkError {
int j=3; k=9;
System。out。println(〃Result of DLL function:〃
+ Add(j;k));
}
/** @dll。import(〃MYMATH〃; entrypoint = 〃#3〃) */
private static native int Add(int op1;int op2);
}
可以看出,唯一的差异就是entrypoint 自变量的形式。
2。 将@dll。import 应用于整个类
@dll。import 引导命令可应用于整个类。也就是说,那个类的所有方法都是在相同的DLL 里实现的,并具有
相同的链接属性。引导命令不会由子类继承;考虑到这个原因,而且由于 DLL 里的函数是自然的 static 函
数,所以更佳的设计方案是将API 函数封装到一个独立的类里,如下所示:
/** @dll。import(〃USER32〃) */
class MyUser32Access {
public static native int
MessageBox(int hwndOwner; String text;
String title; int fuStyle);
public native static boolean
MessageBeep(int uType);
}
public class WholeClass {
public static void main(String args'')
throws UnsatisfiedLinkError {
MyUser32Access。MessageBeep(4);
MyUser32Access。MessageBox(0;
〃Created by the MessageBox() Win32 func〃;
〃Thinking in Java〃; 0);
}
}
由于MessageBeep()和 MessageBox()函数已在不同的类里被声明成 static 函数,所以必须在调用它们时规定
作用域。大家也许认为必须用上述的方法将所有Win32 API (函数、常数和数据类型)都映射成Java 类。但
幸运的是,根本不必这样做。
A。3。2 。ms。win32 包
Win32 API 的体积相当庞大——包含了数以千计的函数、常数以及数据类型。当然,我们并不想将每个Win32
API 函数都写成对应Java 形式。微软考虑到了这个问题,发行了一个Java 包,可通过 J/Direct 将 Win32
API 映射成 Java 类。?
小说推荐
- 软件工程实践者的思想(PDF格式)
- -Page 1-大 道 至 简—软件工程实践者的思想周爱民(Aimingoo 著-Page 2-序2004 年 11 月初爱民(Aimingoo)第一次把他的书稿给我,我翻看了一下,第一反应讲的是感想。这不错,在技
- 最新章:第26章
- 深入浅出MFC第2版(PDF格式)
- -Page 1-Page 2-山高月小山高月小 水落石出水落石出山高月小山高月小 水落石出水落石出-Page 3-深入淺出MFC(第版 使用Visual C 5.0 MFC 4.2)Dissecting MFC(Second Edition Using Visual C 5.0 MFC 4.2)侯俊
- 最新章:第309章
- VB2008从入门到精通(PDF格式英文版)
- -Page 1(R)The eXperT’s Voice inBeginningVB 2008From Novice to ProfessionalChristian Gross-Page 2-Page 3-Beginning VB 2008From Novice to Professional■C
- 最新章:第214章
- C语言游戏编程从入门到精通(PDF格式)
- -Page 1-Page 2-Page 3-Page 4-Page 5-Page 6-Page 7-Page 8-Page 9-Page 10-Page 11-Page 12-Page 13-Page 14
- 最新章:第4章
- JMS简明教程(PDF格式)
- -Page 1-JMS1.1规范中文版卫建军2007‐11‐22-Page 2
- 最新章:第28章
- C语言实例教程(PDF格式)
- -Page 1-前 言Visual C+是开发运行于Windows 95和Windows NT环境下的Win32应用程序的可视化编程工具中最重要的成员之一,它为软件开发人员提供了完整的编辑、编译和调试工具和建立于Win32 API(ApplicationProgramming Interface)基
- 最新章:第143章
- 神祗之眼 (正式版)第7卷(全文完)作者:百里芜虚
- 第五十一章离12月25日的圣诞节还有两天,纽约已经换上了节日的盛装,几天前的一场大雪令整个城市一片银白。人们笑逐颜开,都纷纷开始为节日做准备,商家为了在节日打开销路纷纷推出各种优惠促销手段,纽约的大街小巷全都这样热闹。依沙那被老婆打发出来买过节要用的杂货,而女儿则和凯妮一起到百货商场去买衣服去了。对
- 最新章:第23章
- SQL语言艺术(PDF格式)
- -Page 1-SQLSSQQLL语言艺术内容介绍本书分为12章,每一章包含许多原则或准则,并通过举例的方式对原则进行解释说明。这些例子大多来自于实际案例,对九种SQL经典查询场景以及其性能影响讨论,非常便于实践,为你数据库应用维护人员阅读。资深 SQL 专家 Stéphane Faroult倾力打
- 最新章:第27章
- php程序设计简明教程(DOC格式)
- -Page 1-PHP 程序设计简明教程PHP 讲义 第 1 页 共 90 页-Page 2-目录序 4第一章 PHP 简介 6
- 最新章:第31章