Java动态库调用
2015-08-21 15:50
309 查看
1. 方法简介
a). JNI调用动态库: JNI是安装JDK的时候自带的内容,适用场景为开发前就知道动态库需要供Java程序调用,且需要Java程序提供动态库开发的头文件内容。使用相对复杂,且如果是对于已经存在的动态库需要开发中间库来适配 b). Jacob 调用动态库:Jacob是SUN提供的一个用于调用动态库的类库,使用相对简单,不需要二次开发,但是需要手动进行一些配置工作
c). JNA 调用动态库:JNA是对JNI的二次封装,使用简单,不需要进行二次开发,同样不需要手动进行配置,导入jar包就可以工作
2. JNI调用动态库
假设已经存在一个动态库add.dll,里面存在一个函数int add(int a,int b);现在需要通过JNI去调用这个方法。 ·=> 编写调用中间动态库myAdd.dll的类TestDll.java
·=> 通过命令javah得到中间动态库的头文件TestDll.h
·=> 编写生成中间动态库myAdd.dll
·=> 将生成的myAdd.dll放到TestDll.class同目录下,运行java TestDll查看结果
2.1编写调用中间动态库的类生成TestDll.h
【TestDll.java】public class TestDll { private native static int add(int a, int b); static { System.loadLibrary("myAdd"); // 该动态库名称为中间动态库,由java程序使用,负责调用需要使用的动态库。 } /** * @param args */ public static void main(String[] args) { System.out.println(add(4, 5)); } }
进入cmd执行javac TestDll;javah TestDll
【TestDll.h】
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class TestDll */ #ifndef _Included_TestDll #define _Included_TestDll #ifdef __cplusplus extern "C" { #endif /* * Class: TestDll * Method: add * Signature: (II)I */ JNIEXPORT jint JNICALL Java_TestDll_add (JNIEnv *, jclass, jint, jint); #ifdef __cplusplus } #endif #endif
2.2 编写中间动态库myAdd.dll
使用vc工具先生成win32 Dynamic-Link Library空工程,将上面生成的头文件TestDll.h添加进去,同时还需要添加jdk下include目录中 的jni.h、jni_md.h这两个头文件,最好将jni.h文件放入安装目录下include的目录下,添加调用需要使用的动态库的实现文件TestDll.cpp【TestDll.cpp】
//TestDll.cpp #include <windows.h> #include "TestDll.h" typedef int (*padd)(int,int); JNIEXPORT jint JNICALL Java_TestDll_add (JNIEnv *, jclass, jint x, jint y) { HINSTANCE hins = ::LoadLibrary("add.dll"); if(hins == NULL) { return 0; } int res; padd pa = (padd)GetProcAddress(hins,"add"); if(pa != NULL) { res = pa(x,y); } ::FreeLibrary(hins); return res; }
编译生成myAdd.dll,将myAdd.dll和add.dll放到TestDll.class同目录下,运行java TestDll查看结果为: 9
至此JNI调用动态库完成~
3. Jacob 调用动态库
3.1 Jacob开发环境配置
下载jacob需要的库 Jacob.zip解压后将jacob.jar复制到项目中,或者将其加入到ClassPath中。将jacob-1.18-x86.dll放入到jdk的bin目录中
3.2 注册动态库获取ClassID以及ProgID
设动态库名称为mydll.dll=> 编写windows批处理文件regMyDll.bat,记事本打开编辑regsvr32 mydll.dll双击执行,在win8下可能要右键以管理员身份运行
=>Win + R输入regedit打开注册表,编辑->查找mydll.dll,得到ClassID: 135CB56E-FDB4-43B6-A386-CD0C15295C07;ProgID: WebScan.WScan.1 (一般我们只取ProgID 即可)
3.3 编写调用动态库的类
创建ActiveX控件对象,由于classid每次注册可能会不一样,所以取ProgID作为ActiveXComponent初始化的入参【TestJcob.java】
public class TestJcob { private static ActiveXComponent activeX;//ActiveX控件对象 private static Dispatch dispath;//MS级别的调度对象 static { //创建ActiveX控件对象 //activeX = new ActiveXComponent("CLSID:135CB56E-FDB4-43B6-A386-CD0C15295C07"); activeX = new ActiveXComponent("WebScan.WScan.1"); //获得调度对象 dispath = activeX.getObject(); } public static int add(int a,int b){ Variant ret = Dispatch.call(dispath, "add",a,b); return ret.getInt(); } /** * @param args */ public static void main(String[] args) { System.out.println(add(4,5)); } }
3.4 读取未知dll的函数接口(感兴趣的可以研究下)
将未知dll或者ocx或其他注册,使用VS提供的C:\Program Files\Windows Kits\8.0\bin\x86工具oleview.exe来查看dll的内部变量定义以及函数结构使用方法:打开工具File->View TypeLib选择未知dll查看
4. JNA 调用动态库
下载jna.jar文件,复制并依赖到项目中设调用的动态库名字为Add.dll内部函数为int add(int a,int b);
【TestJNA.java】
public class TestJNA { public interface Add extends StdCallLibrary { Add instance = (Add) Native.loadLibrary(System.getProperty("user.dir") + "\\Add.dll", Add.class); int add(int a,int b); } public static int add(int a,int b){ return Add.instance.add(a, b); } public static void main(String[] args) { System.out.println(add(4,5)); } }
相关文章推荐
- 一:HTML文本编译器 kindeditor-4.1.10 的使用 SpringMVC+jsp的实现
- 大写数字金额
- spring揭秘 读书笔记 二 BeanFactory的对象注册与依赖绑定
- spring揭秘 读书笔记 二 BeanFactory的对象注册与依赖绑定
- Eclipse常用快捷键
- eclipse快捷键大全
- 打包jar文件
- Java中的泛型方法
- 【转】跟着开涛学SpringMVC
- 简述Struts开发流程
- JAVA基础之数组,List,MAP。排序,最值
- servlet面试时遇到问题和Eclipse中servlet显示无法导入javax.servlet包问题的解决方案
- IOS APNS 含java服务器实现
- Java关键字final、static使用总结
- 【我的技术我做主】那些年从事过的.NET,追求的Java
- struts2学习第一篇 环境配置 之 登录页面
- spring quartz cron表达式
- Java进阶03 IO基础
- 第20章 Struts2框架技术
- 常见的java 错误--转