本文主要介绍分别利用JNA和JNI技术实现JSP调用DLL,整个过程均在命令行进行。相关配置如下:
- JNA项目地址
C:\Users\Tristan\Desktop\demo\dell
JNI项目地址C:\Users\Tristan\Desktop\demo\test
- JDK版本
java version "1.8.0_131"
- Tomcat版本
Apache Tomcat/7.0.64
- VS版本
Microsoft Visual Studio 2010 x64
JNA
JNA(Java Native Access):建立在JNI之上的Java开源框架,SUN主导开发,用来调用C、C++代码。
利用JNA技术实现JSP调用DLL文件的步骤如下:
-
编写
DLL.dll
文件
首先编写DLL.cpp
文件#include "DLL.h" int GetInt(int a,int b) { return a+b; }
然后编写
DLL.h
文件extern "C" __declspec(dllexport) int GetInt(int a, int b);
__declspec是Microsoft VC中专用的关键字,它配合着一些属性可以对标准C/C++进行扩充。__declspec关键字应该出现在声明的前面。
__declspec(dllexport)用于Windows中的动态库中,声明导出函数、类、对象等供外面调用,省略给出.def文件。即将函数、类等声明为导出函数,供其它程序调用,作为动态库的对外接口函数、类等。
打开visual studio 命令行,切换到
DLL.cpp
路径下,运行命令,编译生成DLL.dll
文件。cl/LD DLL.cpp
-
编写
DllTest.java
文件首先下载JNA需要的jar包
jna-4.0.0.jar jna-platform-4.0.0.jar
将其放在项目文件下lib文件夹下。
然后编写
DllTest.java
文件package cn; import com.sun.jna.Library; import com.sun.jna.Native; public class DllTest { public interface CLibrary extends Library { CLibrary INSTANCE = (CLibrary) Native.loadLibrary("DLL", CLibrary.class); public int GetInt(int a, int b); } public int add(int a, int b) { return CLibrary.INSTANCE.GetInt(a,b); } }
在windows命令行下运行编译命令
javac -classpath ".;C:\Users\Tristan\Desktop\demo\jnatest\lib\*" -d . DllTest.java
-classpath用来制定需要导入包的位置,可以看到在项目文件下生成包文件夹cn,里面生成两个class文件。
-
jnatest.jsp
文件的编写
首先修改tomcat conf文件下的server.xml文件,修改web应用的发布目录为本地项目目录。<Context path="/dell" docBase="C:\Users\Tristan\Desktop\demo\dell"/>
将本地项目目录lib下的两个jar包复制到tomcat lib文件夹下。
将DLL.dll文件复制到
C:\Windows\System32
路径下。将cn文件夹复制到项目路径
C:\Users\Tristan\Desktop\demo\dell\WEB-INF\classes
下,自己建立WEB-INF文件夹。编写
jnatest.jsp
文件<%@ page import="cn.*" %> <html> <head></head> <body> <% String str; DllTest te = new DllTest();%> <h3> <%=te.add(2,3)%> </h3> </body> </html>
最后启动Tomcat,在浏览器地址栏输入
http://127.0.0.1:8080/dell/jnatest.jsp
可以看到正确的运行结果,JSP成功实现调用DLL。
JNI
JNI(Java Native Interface),从Java 1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。
利用JNA技术实现JSP调用DLL文件的步骤如下:
-
编写带有native声明的方法的java类
Util.java
package com.jni; public class Util{ public native static int add( int x, int y ); static{ System.loadLibrary( "Util" ); } }
使用javac命令编译
Util.java
文件javac -d . Util.java
-
生成对应的头文件
在命令行利用javah命令生成.h文件javah com.jni.Util
可以看到在项目所在路径下生成
com_jni_Util.h
文件 -
编写生成.dll文件
首先创建对应的Util.cpp
文件#include "com_jni_Util.h" JNIEXPORT jint JNICALL Java_com_jni_Util_add (JNIEnv *env, jclass jc, jint x, jint y) { return x+y; }
将
D:\Program Files\Java\jdk1.6.0_26\include\jni.h
和D:\Program Files\Java\jdk1.6.0_26\include\win32\jni_md.h
这两个文件拷贝到项目路径下,在visual studio 命令行,运行命令,生成Uil.dll文件。cl/LD Util.cpp
-
编写test.jsp文件
首先将Util.class打包成jar包,并将其复制到放Tomcat lib路径下。jar -cvf myUtil.jar com
将Util.dll文件复制到
C:\Windows\System32
路径下。编写test.jsp文件
<%@ page import="com.jni.Util" %> <html> <head></head> <body> <h3>7+7=<%=Util.add( 7, 7 )%></h3> </body> </html>
最后启动Tomcat,在浏览器地址栏输入
http://127.0.0.1:8080/test/test.jsp
可以看到正确的运行结果,JSP成功实现调用DLL。
总结
JNI步骤繁琐,JNA简单,而且能够直接调用现有的dll文件,JNI不能直接调用现有的dll文件,还要对cpp文件修改,工作量大。
使用JNA实现java调用c++的源程序在下面链接可以下载到。
JNA实现源码