视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
利用JNative实现Java调用动态库
2025-10-03 14:43:09 责编:小OO
文档
利用JNative实现Java调用动态库  

2008-07-07 15:02:18|  分类: 默认分类 |  标签: |字号大中小 订阅 

由于项目要求,需要用Java调用windows的dll文件,查了一下,如果用JNI的话是比较麻烦的,在sourceforge.net上搜索了一下“Java dll”,首先出现的是Jnative,于是决定用它,后来也试了些别的,但还是JNative好使,简单总结如下:

Java调用动态库所需要关心的问题:

l         如何装载dll文件,以及如何定位所要使用的方法;

l         数据类型是如何对应的;

l         如何给使用的方法传递参数;

l         如何获取返回的值。

JNative INFO:

Resource URL: http://jnative.sourceforge.net/ 

Source Code: http://sourceforge.net/projects/jnative 

Detailed Review: http://jnative.free.fr

JavaDOC: http://jnative.free.fr/docs/

Version:1.3

一个开源的组件,通过它调用已有动态库中的方法就非常的方便,支持CallBack 。

为什么选择JNative

同类的开源组件相对活跃的还有,JNA ( Java Native Access ), Jawin,Nativecall,etc.但是Jnative 相对更容易使用,它对数据类型的处理做的更好。

l         JNA 需要用户对所使用的DLL文件事先进行封装,才能装载。另外需要在一个java接口中描述目标DLL中的函数与结构,从而使JNA自动实现Java接口到native function的映射,较麻烦。

l         Nativecall 暂时还不知道如何装载dll文件。

l         Jawin 数据类型匹配相当敏感,它采用一种叫做”instruction string”的格式来传递参数,还没有完全理解。

How to:

解压JNative-1.3.2.zip 获得三个文件,分别是:JNativeCpp.dll,libJNativeCpp.so,JNative.jar 。

JNativeCpp.dll Windows下用的,拷到windows / system32目录下;

libJNativeCpp.so Linux下的咚咚;

JNative.jar 这是一个扩展包,将其copy到C:\\jdk\\jre\\lib\\ext 下(我的目录结构),系统会自动加载。

结构映射(Structure Mapping)

TypeLength 

JNative class
DWORD4org.xvolks.jnative.misc.basicStructures.LONG
HWND4org.xvolks.jnative.misc.basicStructures.HWND
COLORREF 4org.xvolks.jnative.misc.basicStructures.LONG
COLORREF*4org.xvolks.jnative.pointers.Pointer
LPARAM4org.xvolks.jnative.misc.basicStructures.LPARAM
LPCCHOOKPROC4org.xvolks.jnative.util.Callback
LPCTSTR4org.xvolks.jnative.pointers.Pointer
 

 

 

 

 

 

 

 

方法

Class作用一般用到的方法(参数略,参考Doc)

org.xvolks.jnative.Jnative装载dll文件,定位函数

JNative(),setParameter(),setRetVal(),getRetVal() etc.
org.xvolks.jnative.pointers.Pointer替代本地函数中的的指针,需要先申请一块内存空间,才能创建Pointer(),dispose()

org.xvolks.jnative.pointers.memory.MemoryBlockFactory申请一块内存空间createMemoryBlock()
org.xvolks.jnative.exceptions.NativeException抛出装载,定位等方面的异常
org.xvolks.jnative.Type列举和管理Jnative需要的不同的数据类型

 

简单测试,Javadoc 下和官方网上有些例子,下面的是我随便从IC读卡程序中找了个DLL进行的测试:

SCReader.dll 下的SCHelp_HexStringToBytes()函数原型 

SCREADER_API WINAPI long SCHelp_HexStringToBytes(

LPCTSTR pSrc,

BYTE* pTar,

int MaxCount

);

注意:dll文件需要放到System32下,否则可能找不到

通过Jnative 用java 来调用代码如下

package onlyfun.dllcall;

import org.xvolks.jnative.JNative;

import org.xvolks.jnative.exceptions.NativeException;

import org.xvolks.jnative.pointers.Pointer;

import org.xvolks.jnative.pointers.memory.MemoryBlockFactory;

import org.xvolks.jnative.Type;

public class UserCall {

    /**

    * return 转换成功的字节数

    */

    static JNative Something = null;

    static Pointer pointer;

    public String getSomething(String pSrc, Pointer pTar, int MaxCount) throws NativeException, IllegalAccessException{

      

       try{

           if(Something == null){

              pTar = new Pointer(MemoryBlockFactory.createMemoryBlock(36));

              Something = new JNative("SCReader.DLL", "SCHelp_HexStringToBytes");

// 利用org.xvolks.jnative.JNative 来装载 SCReader.dll,并利用其SCHelp_HexStringToBytes方法

              Something.setRetVal(Type.INT);

// 指定返回参数的类型

           }

           int i=0;

           Something.setParameter(i++,pSrc);

           Something.setParameter(i++,pTar);

           Something.setParameter(i++,MaxCount);

           System.out.println("调用的DLL文件名为:"+Something.getDLLName());

           System.out.println("调用的方法名为:"+Something.getFunctionName());

//传值

           Something.invoke();//调用方法

           return Something.getRetVal();

       }finally{

           if(Something!=null){

              Something.dispose();//释放

           }

       }

    }

    public Pointer creatPointer() throws NativeException{

       pointer = new Pointer(MemoryBlockFactory.createMemoryBlock(36));

       pointer.setIntAt(0, 36);

       return pointer;

    }

    public static void main(String[] args) throws NativeException, IllegalAccessException {

       UserCall uc = new UserCall();

       String result = uc.getSomething("0FFFFF", uc.creatPointer(), 100);

       System.err.println("转换成功的字节数为:"+result);

       TestCallback.runIt();

    }

}下载本文

显示全文
专题