MES系列--(2)JNA使用介绍

JNA:java native access! 有人说是JNI的升级版,其实用过后,你发现不是这样的,JNA没有JNI强大,在某些情况下,用起来比JNI简单一些而已。上篇JNI入门,大家可以看到编写JNI去访问本地代码的步骤已经很规矩死板了,如果你提前有了本地代码如dll文件,那“恭喜”你,你得封装一层了,JNI中,你本地代码的函数名称,参数都是有要求的!JNA就在这里有了突破,你可以先拥有本地代码,然后写Java代码去适配本地代码,而不是JNI中让本地代码去适配你的Java代码。

我在实际应用中,因为大多是先有本地代码(硬件厂商提供的硬件驱动),所以JNA还是能发挥一定作用,直接上例子吧。我们现在有一个IC卡读卡器,硬件厂商提供了访问硬件的dll文件(Windows平台),其中对应的一个函数定义为:

#define MAX_BUFFER_SIZE 2048

#define MYLIBAPI  extern   "C"   __declspec( dllexport )  

MYLIBAPI char* readCardId(int, int);


函数readCardId就是这个dll文件的导出函数,接受两个int类型参数,返回char数组,即卡号。这个函数是不符合JNI规范的,如果我们使用JNI去访问这个函数,是必须封装一层去转调这个函数。但有了JNA,我们有了另一中选择。我们可以直接Java代码,先把这段Java代码贴出来,再给大家分析:

package cn.test;

import com.sun.jna.Library;
import com.sun.jna.Native;

public interface IReadCard extends Library{
	
	public static final IReadCard INSTANCE = (IReadCard)

	Native.loadLibrary("ICCardReader", IReadCard.class);
	
	String readCardId(int antenum, int readcount);
}


这是一个Java接口,继承自Library,来自JNA相关的jar包(我的资源中有下载)。接口中定义了一个函数,String readCardId (int , int),这个函数必须要和dll文件中的函数进行对应(JNI中定义了Java和C++之间的类型对应关系,大家可以参考JDK相关文档)。然后这个接口中通过JNA中的类Native.loadLibrary去加载相关的dll文件,本例中为ICCardReader,并返回一个接口实例对象!给实例对象的方法调用就会调到本地方法中。注意,加载本地代码库文件时,不要加后缀,这是为平台的无关性,Windows平台下,库文件为dll,而Linux下为so后缀!

JNA的编写确实很快,因为你直接去写Java来适配本地代码即可!写完了,就可以调用了。但有些情况,建议还是封装一层:如果你的本地代码中函数的参数类型很复杂,无法或很难和Java这边进行对应,建议你还是重新封装一下,提供一个参数简单的函数供JNA这边使用,毕竟不同语言间类型这块的转换很容易出现问题,尤其对复杂类型。

再稍微谈一下JNA吧,JNA底层是完全基于JNI的,JNA提供的jar包负责的就是这种调用间转换。其实最后的调用过程还是JNI那套。所以JNA的效率会低于JNI。并且因为JNA对于本地代码没有要求,所以本地代码是无法回调Java端代码的,JNI中本地代码可以回调Java中的代码。

总结一下,JNA对于一些函数参数和返回值比较简单的本地代码的调用非常便捷,并且其中不能回调Java端代码(这个实际用的也不多)。如果本地代码的参数和返回值比较复杂,使用JNA建议也要封装一层。

最后再稍带提一下:跨平台调用,最难解的地方就是数据类型的转换了!所以如果你认为某个本地代码库是为了Java平台去调用,那么就提前保证其中函数参数的简单性吧,不要用好多复杂的参数!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
注:下文中的 *** 代表文件名中的版本号。 # 【jna-***.jar中文文档.zip】 中包含: 中文文档:【jna-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【jna-***.jar下载地址(官方地址+国内镜像地址).txt】 Maven依赖:【jna-***.jar Maven依赖信息(可用于项目pom.xml).txt】 Gradle依赖:【jna-***.jar Gradle依赖信息(可用于项目build.gradle).txt】 源代码下载地址:【jna-***-sources.jar下载地址(官方地址+国内镜像地址).txt】 # 本文件关键字: jna-***.jar中文文档.zip,java,jna-***.jar,net.java.dev.jna,jna,***,com.sun.jna,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【jna-***.jar中文文档.zip】,再解压其中的 【jna-***-javadoc-API文档-中文(简体)版.zip】,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件; # Maven依赖: ``` <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>***</version> </dependency> ``` # Gradle依赖: ``` Gradle: implementation group: 'net.java.dev.jna', name: 'jna', version: '***' Gradle (Short): implementation 'net.java.dev.jna:jna:***' Gradle (Kotlin): implementation("net.java.dev.jna:jna:***") ``` # 含有的 Java package(包)(此处仅列举3个): ``` com.sun.jna com.sun.jna.internal com.sun.jna.platform ...... ``` # 含有的 Java class(类)(此处仅列举3个): ``` com.sun.jna.AltCallingConvention com.sun.jna.Callback com.sun.jna.Callback.UncaughtExceptionHandler ...... ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值