[转]如何在Java中调用DLL方法
转载地址:http://developer.51cto.com/art/200906/129773.htm
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中调用Python代码
有时候,我们会碰到这样的问题:与A同学合作写代码,A同学只会写Python,而不会Java, 而你只会写Java并不擅长Python,并且发现难以用Java来重写对方的代码,这时,就不得不想方设法“调 ...
- java中调用dll文件的两种方法
一中是用JNA方法,另外是用JNative方法,两种都是转载来的, JNA地址:http://blog.csdn.net/shendl/article/details/3589676 JNativ ...
- 在java中调用python方法
1.http://sourceforge.net/projects/jython/下载jython包,把其中的jython.jar添加到工程目录 示例: 1.摘自:http://blog.csdn.n ...
- 如何在Java中避免equals方法的隐藏陷阱
摘要 本文描述重载equals方法的技术,这种技术即使是具现类的子类增加了字段也能保证equal语义的正确性. 在<Effective Java>的第8项中,Josh Bloch描述了当继 ...
- java中调用js脚本
JDK1.6加入了对Script(JSR223)的支持.这是一个脚本框架,提供了让脚本语言来访问Java内部的方法.你可以在运行的时候找到脚本引擎,然后调用这个引擎去执行脚本.这个脚本API允许你为脚 ...
- 在Java中调用Python代码
极少数时候,我们会碰到类似这样的问题:与A同学合作写代码, A同学只会写Python,不熟悉Java ,而你只会写Java不擅长Python,并且发现难以用Java来重写对方的代码,这时,就不得不想方 ...
- JDK1.7中调用javascript方法
import java.io.File; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.s ...
- 在C++中调用DLL中的函数
如何在C++中调用DLL中的函数 应用程序使用DLL可以采用两种方式:一种是隐式链接,另一种是显式链接.在使用DLL之前首先要知道DLL中函数的结构信息.Visual C++6.0在VC\bin目录下 ...
- 用代码说话:如何在Java中实现线程
并发编程是Java语言的重要特性之一,"如何在Java中实现线程"是学习并发编程的入门知识,也是Java工程师面试必备的基础知识.本文从线程说起,然后用代码说明如何在Java中实现 ...
随机推荐
- jQuery cdn使用介绍
如果您不希望下载并存放jQuery,那么也可以通过 CDN(内容分发网络)引用它,下面是具体实现,有类似需求的各位可以参考下哈,希望对你有所帮助 如果您不希望下载并存放 jQuery,那么也可以通 ...
- Codeforces Beta Round #78 Div. 1 A
题目链接:http://codeforces.com/contest/98/problem/A 题意大意:给你6种颜色,这6种颜色可能相同也可能不同,把这几种颜色全涂在一个正方体表面,问有多少种涂法( ...
- Android课程---首学开发
新建一个Activity2类: package com.hanqi.test; import android.app.Activity; import android.os.Bundle; impor ...
- Careercup | Chapter 8
8.2 Imagine you have a call center with three levels of employees: respondent, manager, and director ...
- ThinkPHP3.2.3 的异常和错误屏蔽处理
一.入口文件关闭调试,配置文件配置异常页面 在生产环境中系统的错误信息不能暴露给用户,入口文件的 APP_DEBUG 默认为开启状态 define('APP_DEBUG',true); 此时如果用户访 ...
- Android 签名比较
一. keytool -list -printcert -jarfile "%filename%" 二. 非常low方法:下载的应用安装能成功覆盖原应用则签名一致三. 作者:陈子腾 ...
- 【Android测试】【第十八节】Espresso——环境搭建
◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/5604642.html 前言 首先还是老规矩,看看官方文档吧 ...
- SimpleInjector的使用
SimpleInjector的使用 国庆大假,但是,小弟依然学习,前天去看了房交会,尼玛,吓屎宝宝了,还是安静的坐在公司里巧代码比较合适: the usage of injector co ...
- ELK笔记
ELK笔记 ELKStack高级实战培训http://files.cnblogs.com/files/MYSQLZOUQI/ELKStack%E9%AB%98%E7%BA%A7%E5%AE%9E%E6 ...
- JQuery 支持 hide 和 show 事件的方法与分析
问题提出 JQuery不支持hide和show作为事件形式出现, 实际上这两个仅仅是JQuery对象的一个方法(fn): 有一类UI交互需求,根据一个DOM对象的或者显示对附属的DOM对象做相同操作 ...