java

位置:IT落伍者 >> java >> 浏览文章

利用JNative实现Java调用dll动态库


发布日期:2020年06月12日
 
利用JNative实现Java调用dll动态库

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

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

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

l 数据类型是如何对应的

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

l 如何获取返回的值

JNative INFO

Resource URL:

Source Code:

Detailed Review:

JavaDOC

Version

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

为什么选择JNative

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

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

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

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

How to

解压JNativezip 获得三个文件分别是JNativeCppdlllibJNativeCppsoJNativejar

JNativeCppdll Windows下用的拷到windows / system目录下

libJNativeCppso Linux下的咚咚

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

结构映射(Structure Mapping)

Type

Length

JNative class

DWORD

orgxvolksjnativemiscbasicStructuresLONG

HWND

orgxvolksjnativemiscbasicStructuresHWND

COLORREF

orgxvolksjnativemiscbasicStructuresLONG

COLORREF*

orgxvolksjnativepointersPointer

LPARAM

orgxvolksjnativemiscbasicStructuresLPARAM

LPCCHOOKPROC

orgxvolksjnativeutilCallback

LPCTSTR

orgxvolksjnativepointersPointer

一些关键的类及方法

Class

作用

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

orgxvolksjnativeJnative

装载dll文件定位函数

JNative()setParameter()setRetVal()getRetVal() etc

orgxvolksjnativepointersPointer

替代本地函数中的的指针需要先申请一块内存空间才能创建

Pointer()dispose()

orgxvolksmoryMemoryBlockFactory

申请一块内存空间

createMemoryBlock()

orgxvolksjnativeexceptionsNativeException

抛出装载定位等方面的异常

orgxvolksjnativeType

列举和管理Jnative需要的不同的数据类型

(二)

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

SCReaderdll 下的SCHelp_HexStringToBytes()函数原型

SCREADER_API WINAPI long SCHelp_HexStringToBytes(

LPCTSTR pSrc

BYTE* pTar

int MaxCount

);

注意dll文件需要放到System否则可能找不到

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

package onlyfundllcall;

import orgxvolksjnativeJNative;

import orgxvolksjnativeexceptionsNativeException;

import orgxvolksjnativepointersPointer;

import orgxvolksmoryMemoryBlockFactory;

import orgxvolksjnativeType;

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(MemoryBlockFactorycreateMemoryBlock());

Something = new JNative(SCReaderDLL SCHelp_HexStringToBytes);

// 利用orgxvolksjnativeJNative 来装载 SCReaderdll并利用其SCHelp_HexStringToBytes方法

SomethingsetRetVal(TypeINT);

// 指定返回参数的类型

}

int i=;

SomethingsetParameter(i++pSrc);

SomethingsetParameter(i++pTar);

SomethingsetParameter(i++MaxCount);

Systemoutprintln(调用的DLL文件名为+SomethinggetDLLName());

Systemoutprintln(调用的方法名为+SomethinggetFunctionName());

//传值

Somethinginvoke();//调用方法

return SomethinggetRetVal();

}finally{

if(Something!=null){

Somethingdispose();//释放

}

}

}

public Pointer creatPointer() throws NativeException{

pointer = new Pointer(MemoryBlockFactorycreateMemoryBlock());

pointersetIntAt( );

return pointer;

}

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

UserCall uc = new UserCall();

String result = ucgetSomething(FFFFF uccreatPointer() );

Systemerrprintln(转换成功的字节数为+result);

TestCallbackrunIt();

}

}

               

上一篇:数据库连接池java实现小结

下一篇:JSF/JAVA根据IP获取客户端Mac地址