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位系统,目前没找到更好的解决方案,希望大神们给出意见。

1 0
原创粉丝点击