Java语言本身具有跨平台性,如果通过Java调用DLL的技术方便易用,使用Java开发前台界面可以更快速,也能带来跨平台性。
Java调用C/C写好的DLL库时,由于基本数据类型不同、使用字节序列可能有差异,所以在参数传递过程中容易出现问题。
使用Java调用DLL动态链接库的方案通常有三种:JNI, Jawin, Jacob. 其中JNI(Java Native Interface)是Java语言本身提供的调用本地已编译的函数库的方法,本身具有跨平台性,可以在不同的机器上调用不同的本地库。Jawin和 Jacob都是sourceforge.net的开源项目,都是基于JNI技术的依赖Windows的实现,使得在Windows平台下使用COM和 DLL的更加方便。
JNI
JNI的应用方案是基于Java类和本地函数相映射的。其使用Java调用DLL的步骤还是相对比较麻烦,不但涉及到Java编程,还涉及到C/C编程。
JNI的使用步骤是:
1.编写Java类,用该类将DLL对外提供的函数服务进行声明,其中的Java方法均声明为native,其方法签名可以自定义,不用实现函数体。
2.用Javah工具将该Java类生成对应的.h头文件。
3.最重要的比较麻烦的一步:编写C/C代码实现.h头文件中声明的函数,该C/C代码中包含jni.h头文件,并且编写代码时使用其中定义好的数据类型作为函数的输入和返回数据类型进行编程。用这种方法实现数据类型转换。例如数据类型:boolean(java) à jboolean(jni.h: typedef unsigned char jboolean),在自己编写的C/C代码中使用数据类型jboolean映射Java中的boolean类型。在该步骤中,可以在C/C代码中调用已经存在的DLL库。
4.另外编写的Java代码时就可以使用该Java类了。
在第3步中,编写C/C函数时,可以使用一个叫interface pointer的env指针来调用JNI提供的一系列(很多)函数,用这些函数来访问JVM的对象和数据。
使用JNI的缺点:使用比较麻烦,需要对已有的DLL进行封装,需要对C/C比较了解。
使用JNI的优点:可以跨平台调用本地库。
Jawin
Jawin的应用方案是基于函数调用时采用原始字节流传递数据的。就是在Java中指明一个DLL中的某个函数后,通过原始字节流(需要考虑参数数据类型所占的存储字节数及系统使用的字节序列)传递给该DLL函数需要的参数,其返回值也是通过原始字节流解析的方式获得正确的值。
Jawin的使用步骤:
1.环境配置:下载Jawin;Jawin.dll放入工程目录下;Jawin.jar相关jar文件加入到运行库中(LibPath或者Eclipse下配置工程的BuildPath-AddLibrary)。
2.获得函数指针:new FuncPtr("DllFileName.DLL", "dllFunctionName");
3.用LittleEndianOutputStream将函数需要的参数写入到一个原始字节流NakedByteStream。
4.最重要的一步:调用FuncPtr.invoke()。传入参数比较复杂。
5.解析上一步的返回值(字节数组)。
第4步中传入的参数包括:
1.指令字符串。一个"XXX:Y:ZZZ"格式的字符串。其含义分别是传入参数中的每个字节的数据类型意义、返回值的类型、需要从传入指针中读取的数据(inout类型参数)。比如:
函数签名int func(int, int, struct s*, char*); //其中struct s*调用完函数后需要读出,struct s所占字节数为16。
其指令字符串为:IIP16G:I4L4n16L4。该字符串在解析返回值(字节数组)时,首先应该是返回类型I对应的4个字节,然后是inout类型的参数中n16对应的16个字节。
其中字符串的意义可以在Jawin提供的文件instructions.h中找到,或者在官方文档(Jawin数据指令)中找到常用的一些指令字符串的意义。
2.传入参数的总字节大小。
3.前面写好的传入参数的原始字节流。
4.一个object数组。
5.ReturnFlags,用以根据C/C返回值将C/C的错误转换为Java的异常并抛出。其中CHECK_NONE表示不检查;CHECK_FALSE和CHECK_WIN32分别表示返回0是FALSE和 SUCCESS,根据是否出错决定是否抛出异常;CHECK_HRESULT表示使用COM模型中的HRESULT作为返回值,其错误码可以配置。
使用Jawin的缺点:不方便调试,几乎所有的错误都抛出同样的异常COMException;需要对数据类型的转换比较了解;不能跨平台,对Windows的依赖性比较强。
使用Jawin的优点:方便使用,不用进行C/C开发,不用对原始DLL进行封装就可以方便使用。
Jacob
Jacob是Java-Com Bridge的缩写,也可以用来调用DLL。其底层也是使用JNI实现,也具有Windows 的平台依赖性,但是网上有人反映其易用性不如jawin。
相关推荐
JAVA调用DLL JAVA调用DLLJAVA调用DLLJAVA调用DLLJAVA调用DLLJAVA调用DLL
亲测可用,java 成功调用dll函数。包含调用回调函数,springboot版本。最近由于公司业务需要,要调用dll文件,用JNA调用。
java调用本地dll的几种方法性能对比测试。 JNA消耗的总时间(ms):5406 bridj消耗的总时间(ms):984 JNI消耗的总时间(ms):47 包含c++源码和java源码,部署和使用方法。在win7和winxp下测试用过。 部分源码是...
数字转中文<br>128 自动计算金额<br>129 JSP页面打印中使用WebBrowser控件<br>130 <select...>不刷新页面添加新的类别<br>131 鼠标滚动缩放图片<br>132 根据输入的表名生成输入数据表格<br>133 JSP表格输出到Excel...
Java中调用动态库dll的方法一文的源代码
在Java中调用DLL(Dynamic Link Library)文件,可以使用Java的本地方法接口(JNI,Java Native Interface)来实现。JNI允许Java程序与本地代码进行交互,从而实现跨平台的功能。
JAVA如何调用dll:用JNI调用C或C++动态联接库原来如此简单
java调用c++ dll代码
这两天要弄个JAVA调用DLL,研究了一下有点绕, java部分要生成.h头文件,所以弄了个例子在这分享下 JAVA调用DLL完整步骤 步骤里包括java部分代码及vc写的DLL代码
Java调用动态链接库 Java 调用 DLL 源码
Java通过JNI调用DLL动态库,亲测试编写
完整的实现java跨平台调用C程序源码,包含JAVA源码和C源码以及编译后的demo dll。将dll放到jdk bin目录下,java 项目可以直接运行。若要修改dll可以,修改C源码后重新编译生成dll。该demo处理了多线程调用c,全局...
在JAVA中如何通过JNI调用VC动态库,以及在如何在VC中调试
Java调用dll示例,Java命名方法,C++实现生成DLL供JAVA调用
JAVA使用JNative包调用DLL文件
java调用vc的dll,java调用vc的dll,java调用vc的dll,java调用vc的dll
JAVA如何调用dll:用JNI调用C或C++动态联接库原来如此简单
java调用C#封装的dll方法 关于java调用C# 封装的DLL文件的方法 第一种:java利用JNA进行调用 思路:C#源码生成COM组件(dll和tlb文件),再利用C++进行封装,java通过JNA调用C++封装的DLL。 第二种:java利用jacob...
[JAVA]使用JNI技术实现JAVA程序调用dll、[JAVA]使用JNI技术实现JAVA程序调用dll
该资源包含C#开发DLL源码,Java调用DLL源码,测试已通过