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
sun相关文档:http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/jniTOC.html
JNI的完整例子 :http://www.pconline.com.cn/pcedu/empolder/gj/java/0506/642328.html
JNI的应用方案是基于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
官方网站:http://jawinproject.sourceforge.net/
官方文档(Jawin介绍): http://jawinproject.sourceforge.net/jawin.html
官方文档(Jawin使用DLL):http://jawinproject.sourceforge.net/jawinuserguide_dll.html
官方文档(Jawin数据指令): http://jawinproject.sourceforge.net/instruction_docs.html
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:I:L4L4n16L4。该字符串在解析返回值(字节数组)时,首先应该是返回类型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
官方文档:http://danadler.com/jacob/
Jacob是Java-Com Bridge的缩写,也可以用来调用DLL。其底层也是使用JNI实现,也具有Windows 的平台依赖性,由于网上有人反映其易用性不如jawin,所以没有深入了解。
在java中使用Jawin组件访问Win
转自:
http://blog.sina.com.cn/u/5921d4ba010007jo
Author:Howwa@sina.com
日期:2007-2-23(正月初六)
环境:windowsXPHome版;Office2000;j2se1.6.0(JRE也是1.6.0);Jawin2.0-alpha1。
原由:使用Jacob访问windows下的COM组件的试验老是不成功(后来搜索到http://blog.sina.com.cn/u/435ce819010002r0,按他的办法据说可以成功),折腾了我一天。网上有说使用Jawin的,我试了一试就成功了,比Jacob顺利多了。据说Jawin比Jacob功能强大。
(1)Jawin(Java/Win32)是一个免费的、开放源代码的体系结构,用于Java组件与WindowsCOM对象或WindowsDLL之间的互操作。Jawin允许Java应用程序调用任何基于COM或DLL的遗留代码,而不需要编写任何JNI代码。您的代码将能与诸如MicrosoftOffice套件等可编写脚本的应用程序交互,调用诸如Microsoft的基于COM的XML解析器和工具等可编写脚本的逻辑组件,以及访问诸如Windows注册表、安全API和事件日志等Win32API特性。
(2)Jawin包括一个用于可编写脚本的COM组件的代码生成器(typebrowser),该代码生成器读取类型库,并自动产生Java应用程序中调用该组件所需要的Java存根(stub)。
http://sourceforge.net/projects/jawinproject/
Jawin2.0-alpha1下载地址:http://jawinproject.sourceforge.net/
下载文件是一个zip文件,叫jawin-2.0-alpha1.zip。解压缩后,将bin\jawin.dll文件(约264k)拷贝到系统的system32文件夹下,将lib\jawin.jar和lib\jawin-stubs.jar拷贝到C:\J2SE6\jre\lib\ext文件夹下(我的j2seJDK安装在c:\J2SE6文件夹下)。其他设置不需要做。
举例1:CreateWord.java,新建一个Word文档。
/******************************************
*CreateWord.java
*CreateaWorddocument
*
*version1.0
*authorHowwa@sina.com
http://blog.sina.com.cn/u/1495389370
*******************************************/
importorg.jawin.DispatchPtr;
importorg.jawin.win32.Ole32;
publicclassCreateWord{
publicstaticvoidmain(String[]args){
try{
Ole32.CoInitialize();
//初始化
DispatchPtrapp=newDispatchPtr("Word.Application");
//创建word对象
app.put("Visible",true);
//使word可见
DispatchPtrdocs=(DispatchPtr)app.get("Documents");
//获得document对象集合
DispatchPtrdoc=(DispatchPtr)docs.invoke("Add");
//新增一个文档
app.invoke("Activate");
//激活当前文档
Ole32.CoUninitialize();
//释放对象
}catch(Exceptione){
e.printStackTrace();
}
}
}
举例2:OpenWord.java,打开一个已存在的Word文档。
/******************************************
*OpenWord.java
*OpenaWorddocument
*
*version1.0
*authorHowwa@sina.com
http://blog.sina.com.cn/u/1495389370
*******************************************/
importorg.jawin.DispatchPtr;
importorg.jawin.win32.Ole32;
publicclassOpenWord{
publicstaticvoidmain(String[]args){
try{
Ole32.CoInitialize();
DispatchPtrapp=newDispatchPtr("Word.Application");
app.put("Visible",true);
DispatchPtrdocs=(DispatchPtr)app.get("Documents");
DispatchPtrdoc=(DispatchPtr)docs.invoke("Open","C:\\test.doc");
Ole32.CoUninitialize();
}catch(Exceptione){
e.printStackTrace();
}
}
}
在编译、运行时要注意大小写。同时,C盘根目录下要有test.doc文件。
/*
*CreateWordDoc.java
*
*1.Createanewworddocument;
*2.assignfontname
*3.assignfontsize
*4.writetwosentences
*5.saveit
*6.closeit
*7.exitword.
*
*@versionvision:1.0
*@authorhowwa@sina.com
*http://blog.sina.com.cn/u/1495389370
*/
importorg.jawin.DispatchPtr;
importorg.jawin.win32.Ole32;
publicclassCreateWordDoc{
publicstaticvoidmain(String[]args){
try{
Ole32.CoInitialize();
//初始化
DispatchPtrapp=newDispatchPtr("Word.Application");
//创建word对象
app.put("Visible",true);
//使word可见
DispatchPtrdocs=(DispatchPtr)app.get("Documents");
//取得document对象集合(Documents)
DispatchPtrdoc=(DispatchPtr)docs.invoke("Add");
//新增一个文档
app.invoke("Activate");
//激活当前文档
DispatchPtrobjTextFont=(DispatchPtr)((DispatchPtr)doc.get("Content")).get("Font");
//取得Font对象
objTextFont.put("Name","黑体");
//设置字体
objTextFont.put("Size","48");
//设置字号
DispatchPtrdocSelection=(DispatchPtr)app.get("Selection");
//取得Selection对象
docSelection.invoke("TypeText","Jawwintesttext!\nJawin测试文本。");
//使用TypeText方法添加文本
doc.invoke("SaveAs","c:\\jawintest.doc");
//保存文档(保存在C盘根目录下)
//doc.invoke("Close");
//关闭当前文档,去掉前面的注释符并重新编译后可生效
//app.invoke("Quit");
//退出Word,去掉前面的注释符并重新编译后可生效
Ole32.CoUninitialize();//释放对象
}catch(Exceptione){
e.printStackTrace();
}
}
}
分享到:
相关推荐
### JAVA调用DLL方法 在跨平台开发领域中,Java作为一种强大的编程语言,因其具有良好的移植性和跨平台性而被广泛使用。然而,在某些特定情况下,我们可能需要调用本地库(例如DLL文件)来实现特定功能或提高性能。...
研究java调用dll的时候,大部分都是通过jni,比较麻烦,我找到了通过jna方法调用dll的方法,用起来比较方便,只需要引用jna.jar包,这个jar包已经包含在程序中,还包含了我调用dll的遇到难道的解决办法。
java调用本地dll的几种方法性能对比测试。 JNA消耗的总时间(ms):5406 bridj消耗的总时间(ms):984 JNI消耗的总时间(ms):47 包含c++源码和java源码,部署和使用方法。在win7和winxp下测试用过。 部分源码是...
在Java中调用DLL(Dynamic Link Library)文件,可以使用Java的本地方法接口(JNI,Java Native Interface)来实现。JNI允许Java程序与本地代码进行交互,从而实现跨平台的功能。
在实际项目中,Java调用DLL通常用于利用已有的C/C++库,或者执行一些Java不擅长的任务,如硬件控制、图形处理等。然而,由于涉及到本地代码,这也会增加程序的复杂性和维护难度,因此在选择这种方法时需要权衡利弊。...
java调用dll方法总结 Java 调用 DLL 方法是一种常用的技术,它允许 Java 应用程序调用本机代码 DLL 文件中的方法。这种技术广泛应用于各种领域,如游戏开发、科学计算、数据分析等。 为什么需要 Java 调用 DLL ...
Java调用DLL是Java开发中一个重要的技术主题,它允许Java程序与本地操作系统API或者其他C/C++编写的动态链接库进行交互。在Java中,有多种方法可以实现这个功能,其中最常用的是Java Native Interface (JNA) 和 ...
### Java调用C#封装的DLL方法 #### 第一种方法:Java利用JNA进行调用 **背景介绍:** 为了实现Java与C#之间的交互,一种常用的方式是通过调用C#封装的DLL文件来完成特定功能。这种方法涉及到.NET Framework与Java...
总结来说,Java调用DLL主要涉及JNI的使用,包括在Java中声明native方法,生成JNI头文件,编写C++代码实现接口,编译链接DLL,以及在Java中加载和调用DLL。这个过程允许Java开发者充分利用C++的高性能特性,同时保持...
总结来说,Java调用DLL文件主要依赖于JNative库,通过定义Java接口、加载DLL、获取函数句柄、创建代理对象以及调用函数等步骤实现。这种方法使得Java开发者能够充分利用C/C++库的功能,同时也保持了Java的跨平台特性...
总结,Java调用C++ DLL的过程主要包括:编写C++ DLL、创建Java JNI接口、生成JNI头文件、实现JNI接口并编译为DLL、最后在Java程序中加载和调用DLL。这个过程虽然有些复杂,但能充分利用现有C++库,拓展Java的功能。...
本主题聚焦于"Java调用DLL接口",这是一个允许Java代码利用Windows系统上的DLL功能的技术。 DLL(Dynamic Link Library)是微软Windows操作系统提供的一种机制,它包含了一组可执行函数和变量,可供多个程序同时...
4. **调用DLL方法**:现在,你可以通过你的接口来调用DLL中的方法。Java会自动处理DLL的加载和方法调用。 5. **测试**:提供的测试程序是一个很好的起点,它展示了如何配置和使用jawin。阅读代码中的注释,了解如何...
JNA是实现Java调用DLL的关键工具,DLL是Windows操作系统中的本地库,而“java调用dll”是整个过程的目标。 在压缩包子文件的文件名称列表中,只有一个文件名"testmj"。通常,这可能是一个测试类或者包含主方法的...
Java调用DLL函数是跨平台编程中的一种常见需求,特别是在Java与C/C++代码交互时。JNA(Java Native Access)是Java平台上的一个库,它允许Java代码直接调用本机库(如DLL文件)的函数,而无需编写JNI(Java Native ...
Java调用Qt DLL是一个跨平台的技术实践,涉及到Java与C++之间的互操作性,其中Qt是一个流行的C++库,主要用于图形用户界面开发。这个主题主要包含以下几个知识点: 1. **JNI(Java Native Interface)**:JNI是Java...
总的来说,通过Java调用DLL实现DES加密解密涉及了Java和C/C++的混合编程,需要理解JNI的工作原理,以及如何在C/C++中与DLL交互。这个过程对于那些希望在Java中利用已有的本地库功能的开发者来说是至关重要的。
总结,Java调用DLL涉及多个步骤,包括Java接口定义、DLL加载、本地方法实现等。`JNative.jar`提供了方便的接口来简化这一过程,而源代码`JNative_1.4RC2_src`有助于理解其工作原理和定制功能。正确使用这些工具,...
Java调用DLL文件是将Java程序与C/C++编写的动态链接库集成的一种技术,主要通过JNI(Java Native Interface)来实现。JNI是Java平台的标准部分,它允许Java代码和其他语言写的代码进行交互。在本实例中,我们将探讨...
### Java调用DLL:JNative概述 在Java项目中,有时候需要调用本地系统的动态链接库(DLL)来实现特定的功能。传统的做法是通过Java Native Interface (JNI)来进行调用,但这往往涉及到复杂的配置和繁琐的过程。为了...