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

标签: 无标签

利用JNative实现Java调用动态库(转)

 

 

 

http://cctv663.blog.163.com/blog/static/101192122008673218691/

由于项目要求,需要用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


 

Type

Length

JNative class

DWORD

4

org.xvolks.jnative.misc.basicStructures.LONG

HWND

4

org.xvolks.jnative.misc.basicStructures.HWND

COLORREF

4

org.xvolks.jnative.misc.basicStructures.LONG

COLORREF*

4

org.xvolks.jnative.pointers.Pointer

LPARAM

4

org.xvolks.jnative.misc.basicStructures.LPARAM

LPCCHOOKPROC

4

org.xvolks.jnative.util.Callback

LPCTSTR

4

org.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 ();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值