jawin方式操作dll动态库
来源:互联网 发布:淘宝cku总统妈妈犬舍 编辑:程序博客网 时间:2024/06/12 11:37
java操作dll库的方法有好几种,今天分享一个jawin方式操作dll的方法。
1.首先下载jawin-2.0-alpha1的jar包和jawin.dll文件,可在官网http://sourceforge.net/projects/jawinproject/处下载也可通过作者上传的资源http://download.csdn.net/detail/u011563755/9107917处免费得到,里边有关于jawin的官方文档和一些官方的demos。
2.第二步将jawin.jar这个jar包拷贝到工程目录,并添加到环境变量中,
3.第三步拷贝jawin.dll文件到工程目录下。
4.第四步找到压缩包中的jawin-2.0-alpha1\demos\demos\HelloDll.java这个文件,将其复制到工程目录下运行之。这个demo是调用win32系统的USER32.DLL库,并且通过
msgBox.invoke_I(0, "Hello From a DLL", "From Jawin", 1, ReturnFlags.CHECK_FALSE);`
向库中传参弹出windows的MessageBox。
当然网上我查阅的资料中都是这样介绍jawin方式调用dll的,但是这个demo还不能全面的使用jawin,因为有些dll中是通过参数[out](传出)数据的,jawin通过什么方式获得参数中的返回值呢?
这里通过查阅jawin的文档,可以找到这样一种方式获得参数中的返回值。
invoke
public byte[] invoke(java.lang.String instructions,
int stackSize,
int argStreamSize,
byte[] argStream,
java.lang.Object[] objectArgs,
ReturnFlags flags)
throws COMException
generic method for calling native methods that do not match any of the invoke_* methods. If the caller is using a NakedByteStream for building the stack-bytes, the invoke(String, int, NakedByteStream, Object[], ReturnFlags) shortcut method is prefered.
Parameters:
instructions - the marshalling instructions for marshalling both the stack-array onto the native stack (this is the [in]-parameters) and marshalling the [return] and [out]-parameters onto the returned byte array. Is on the form xx:y:zz, where xx is for the [in]-marshalling, y is for the [return]-marshalling, and zz is for any [out]-marshalling if present. See the Jawin documentation for more about the instruction-strings.
stackSize - the size of the call stack on the native side that the content of the argStream-array should be marshalled to.
argStreamSize - the number of relevant bytes in the argStream-array (often a NakedByteStream is used for the argStream-array, in which case the array will not be full.
argStream - the bytes that should be marshalled to the stack on the native side. The length of this array can NOT be smaller than argStreamSize.
objectArgs - [in/out] used if any java-object should be passed back and forth into the native code.
flags - used for specifying the native error handling, can not be null.
Returns:
the [return] and [out] parameters from the native call, serialized following the marshalling-instructions given the second and third part of the instructions string.
Throws:
COMException - if the native method failed.
java.lang.NullPointerException - if flags is null.
java.lang.ArrayIndexOutOfBoundsException - if argStreamSize is bigger than the length of the argStream-array.
java.lang.IllegalStateException - if this FuncPtr has been closed.
这是api中的函数介绍,都是英语有点烦,然后我们通过一个例子来说明问题。
1.在vs2010中建立一个dll工程,创建头文件DllDlg.h
#define MYLIBDLL extern "C" _declspec(dllimport) #else#define MYLIBDLL extern "C" _declspec(dllexport) #endif MYLIBDLL int ReturnValue(); MYLIBDLL void OpenDlg(int a); MYLIBDLL int ReturnParam(int a,int& b,int& d);#endif
其中定义了三个导出函数,ReturnValue() OpenDlg() 和 ReturnParam(),接下来看三个函数的实现。
DllDlg.cpp
#include "stdafx.h"#include "DllDlg.h"#include "TestDlg.h"void OpenDlg(int a){ TestDlg dlg; dlg.number = a; dlg.DoModal();}int ReturnValue(){ int a = 88; return a;}int ReturnParam(int a,int& b,int& d){ int c = 3; b = a + 1; d = a + 2; return a + c;}
TestDlg是一个可以做加法运算的对话框在此不介绍。
ReturnValue是一个极其普通的返回一个int数字的函数,ReturnParam的b,d参数则是返回型的参数。接下来编译生成我们的dll库。
2.在eclipse修改demo HelloDll.java如下:
import org.jawin.COMException;import org.jawin.FuncPtr;import org.jawin.ReturnFlags;import org.jawin.io.LittleEndianOutputStream;import org.jawin.io.NakedByteStream;import org.jawin.marshal.StructConverter;/** * Demo that uses the Win32 MessageBoxW API-method. * * @version $Revision: 1.3 $ * @author Stuart Halloway, http://www.relevancellc.com/halloway/weblog/ */public class HelloDll { public static void main(String[] args) throws Exception { FuncPtr funPoint = null; try { funPoint = new FuncPtr("E:\\VS2010 Project\\Java_Dll\\Debug\\Java_Dll.dll","ReturnParam");//得到dllReturnParam的函数指针 NakedByteStream nbs = new NakedByteStream();//创建数据流 LittleEndianOutputStream leos = new LittleEndianOutputStream(nbs); leos.writeInt(6);//在数据流中传入参数([in]类型参数这里指int ReturnParam(int a,int& b,int& d)中的a) //IAA:I:L4n4n4字符串是jawin规定的一种伪指令具体书写格式按照文档instruction_docs.html中介绍 //第一个I表示[in] long parameters 也就是ReturnParam的参数a,第二个和第三个AA表示[out] long* parameters也就是ReturnParam的参数b c,第一个:后表示返回值的类型, //第二个:后表示数据类型所占位数a是int型所以是long类型4字节,&b &c都是int型指针也占4字节, byte[] result = funPoint.invoke("IAA:I:L4n4n4", 12/*返回值所占字节数*/, nbs, null, ReturnFlags.CHECK_FALSE); System.out.println(StructConverter.bytesIntoInt(result, 0));//得到的返回值result中前四位表示的是返回值6+3 System.out.println(result[4]);//参数返回值6+1 System.out.println(result[8]);//参数返回值6+2 /*ReturnParam()函数 * int ReturnParam(int a,int& b,int& d) { int c = 3; b = a + 1; d = a + 2; return a + c; }*/ } catch (COMException e) { // handle exception e.printStackTrace(); throw e; } finally { if (funPoint != null) { try { funPoint.close(); } catch (COMException e) { // handle fatal exception e.printStackTrace(); throw e; } } } }}
E:\VS2010 Project\Java_Dll\Debug\Java_Dll.dll为刚才vs2010创建的dll库。得到结果:
978
工程下载路径:
http://download.csdn.net/detail/u011563755/9108083
作者的jawin测试demo是在32为系统上运行的,在64位的系统上运行会报错,提示不能加载32位的dll到64位系统,目前没找到更好的解决方案,希望大神们给出意见。
- jawin方式操作dll动态库
- [转]Java调用DLL动态链接库的方案:JNI, Jawin, Jacob.
- jawin如果调用dll
- 通过 jawin 调用dll库(no jawin in java.library.path)
- jawin操作word
- 动态库dll加载方式
- 用jawin动态生成word
- Java调用本地库,如调用DLL或者SO,如:JNI, Jawin, Jacob,JNative,JNA
- JNA方式调用dll动态库
- dll动态加载方式
- 动态库DLL加载方式-静态加载和动态加载
- 动态库DLL加载方式-静态加载和动态加载
- 动态库DLL加载方式-静态加载和动态加载
- dll动态加载的方式
- dll动态加载的方式
- dll动态加载的方式
- dll动态加载的方式
- dll动态加载的方式
- ButterKnife--View注入框架
- QT4.8.4+DirectFB1.4.3
- 20150913K-means聚类.md
- 根据命令行生成cxf客户端
- 设计模式之建造者模式
- jawin方式操作dll动态库
- activity中用到多个fragment,资源被回收后,出现未知异常
- libevent 编程 二:bufferevent
- tableView取消选中行的选中状态
- 国内常用ntp服务器
- Hibernate联合主键映射
- 调优
- nginx编译相关知识
- Application Loader报错 cannot proceed with delivery: an existing transporter....