jawin方式操作dll动态库

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库。得到结果:

9
7
8

工程下载路径:
http://download.csdn.net/detail/u011563755/9108083

作者的jawin测试demo是在32为系统上运行的,在64位的系统上运行会报错,提示不能加载32位的dll到64位系统,目前没找到更好的解决方案,希望大神们给出意见。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值