孙文华,刘 平
(南昌工程学院 信息工程学院,江西 南昌 330099)
虽然Java和VC++是当前两大主流的编程语言,但是如果两者之间不能有效结合,实现相互调用的话,势必会给编程人员的工作带来诸多不便,增加许多的重复工作,甚至有可能造成整个项目的搁浅。另外,不同语言之间的互相调用还可以有效地利用现有程序,并且不需要一遍一遍地撰写类似的程序代码。为此,本文引人了VC++中的动态链接库文件,通过实例阐述了如何在Java中成功调用VC++动态链接库的问题[1]。
动态链接库DLL好比一个封装起来的 “仓库”,DLL是Dynamic Link Library的缩写,其中封装了一些或者部分可以被共享的例程和资源,采用动态的连接方式就能够被其他程序动态装载、运行以完成某些特定的功能。
采用动态链接库进行软件开发,具体优势主要有下面几点:
(1)对硬件资源方面的要求比较小
在程序开发过程中,经常遇到多个程序调用同一个函数库的情况,这时如果使用动态链接库,就可以大大减少在磁盘和物理内存中重复代码的加载。只有当生成的EXE文件确实要调用该DLL模块时,系统才会将其加载到内存空间中去。
(2)项目体系结构模块化开发
程序结构模块化对项目开发有着重要的作用,能够方便项目的管理与功能的定制。动态链接库的设计包含这种思想。另外,动态链接库支持多语言。这样可以有更广阔的应用平台,方便开发程序的移植,也可以在不同的开发平台上调用。通常当开发的系统为庞大系统,避免不了有许多重复类型的功能,这时如果将这些类似的功能单独做成DLL,将可以大大减少开发的工作量和提高开发的速度[2]。
(3)软件维护方便
当动态链接库中的函数需要更新或修复时,采用动态链接库更方便。因为部署及安装动态链接库在此就不要求重新建立程序与该DLL的连接。此外,如果多个程序使用同一个DLL,则多个程序都将从该更新或修复中获益。当使用定期更新或修复的第三方DLL时,此问题可能会更频繁地出现,升级到DLL就可以更容易解决这些问题。
(4)功能实现的细节隐藏
考虑到一些重要技术的保密和知识产权的保护,在某些情况下,通常将项目中一些功能实现的具体细节隐藏起来,即希望里面的部分代码不被公开,这时动态链接库就是一项非常不错的实现方法。动态链接库可以被其他应用程序访问调用,但将代码的具体细节完全隐藏起来。另外,DLL的语言无关性也是很重要的一个方面。正是由于动态链接库DLL与语言无关的这个特点,故用VC++创建的DLL可以被其他任何支持动态链接库的编程语言调用,比如 VB、Delphi、PD[3]等。
JNI(Java Native Interfacejava)其实就是指 Java本地程序接口,属于JDK中的一部分。当Java程序中有需要调用通过VC++语言编写的DLL时,此时最佳选择就是使用JNI技术。通过使用Java本地接口书写程序,可以确保代码在不同的开发平台上方便移植。JNI使得运行于Java虚拟机的代码可以操作用C、C++或者汇编等书写的应用程序或库,同时也可以通过调用相应的接口函数将Java虚拟机内嵌到本地应用程序中。
特别需要提醒的是,只要有下面几种情况中的任何一种出现时,程序员就需要利用JNI来进行处理:(1)所开发的应用程序要使用到与平台相关的属性,但Java标准类库不支持对这些属性的处理;(2)已经拥有了利用其他编程语言实现的应用程序或库,希望用Java直接调用这些应用程序或库来实现;(3)程序中的某个模块对运行的时间效率要求很高,此时希望用比较低级的语言(如汇编)来实现,同时希望在Java应用程序中使用这个模块[4]。
使用JNI在Java中调用VC++写的 DLL有以下几个步骤:(1)创建 Java类;(2)编译 Java代码并生成头文件;(3)开发 DLL并实现方法;(4)编译动态链接库;(5)测试运行程序。
2.2.1 无包情况
(1)在Java中写调用VC的代码,具体如下:
(2)在运行弹出的输入框中输入cmd进入dos界面,通过cd命令进入到安装Java的路径下面的bin中,假设安装目录是 D:Program FilesJavajdk1.6.0_10in,把JieCheng.java文件移到 D:Program FilesJavajdk1.6.0_10in目录下,输入 javac JieCheng.java,可以看到在该目录下生成了JieCheng.class的文件。输入javah JieCheng生成了JieCheng.h文件。具体如下:
(3)在VC下创建DLL文件,名字一定要是System.load-Library("JieCheng")中的 JieCheng,把 JieCheng.h文件直接复制到该VC文件下,同时把jni.h,jni_md.h复制到VC工程下。在JieCheng.cpp文件下实现在Java中声明过的方法,注意方法名一定要与JieCheng.h中声明的方法一致,在方法中写入代码如下:
(4)在VC下编译生成 JieCheng.dll文件,把该文件直接复制到 Java的安装目录下面的 bin目录下:D:Program FilesJavajdk1.6.0_10in。
(5)把在VC下编译生成的JieCheng.dll文件直接复制到 Java的安装目录的 bin目录下:D:Program FilesJavajdk1.6.0_10in。运行命令:java JieCheng,本例中,JieCheng函数用于求一个数的阶乘,所以在屏幕上显示的结果是“120”。
2.2.2 有包情况
有包的情况与上面介绍的无包情况大致相同。但需要特别强调、引起注意的地方是:首先需要在Java的安装目录bin下创建包名文件夹,假设创建的包名文件夹的名称为NegerVector,然后把.java文件放在此文件夹中。接下来就是进入DOS环境下运行两个命令,首先运行:javac NegerVectorJieCheng.java; 然后运行:javah Neger Vector.JieCheng。其他的可以参照无包情况了,因为接下来与无包的情况基本相同。
在许多大型项目的开发过程中,从提高开发效率以及实现代码重用的角度来看,跨平台服务的开发是未来的发展趋势,从而经常需要在Java程序中调用VC中的DLL。本文从JNI技术出发,通过简单的实例详细阐述了JNI调用VC++写的DLL的程序,解决了Java与VC的有效结合,实现了它们之间的相互调用。
[1]王志文,夏秦,李平均.Java程序设计(修订本)[M].西安:西安交通大学出版社,2005.
[2]孙文华.一种基于Java编程的脏字过滤器的设计[J].微型机与应用,2012,31(9):18-19,23.
[3]王敏,邵定宏,陆金桂.动态链接库技术及其应用实[J].微计算机信息,2006,22(27):272-274.
[4]宋晓字,王永会.Visual C++高级编程技术与实例[M].北京:中国水利水电出版社,2006.