java 动态加载jar中的方法 java jna 加载动态库

您所在的位置:网站首页 jna是什么病 java 动态加载jar中的方法 java jna 加载动态库

java 动态加载jar中的方法 java jna 加载动态库

2023-09-20 22:22| 来源: 网络整理| 查看: 265

 

Java 调用 DLL 无非三种方法:JNI、JNA、JNative

1 JNA是什么

JNA(JavaNativeAccess)框架是一个开源的Java框架,是SUN公司主导开发的,建立在经典的JNI的基础之上的一个框架。 JNA项目地址:https://jna.dev.java.net/ JNA使Java调用原生函数就像.NET上的P/Invoke一样方便、快捷。 JNA的功能和P/Invoke类似,但编写方法与P/Invoke截然不同。JNA没有使用Annotation,而是通过编写一般的Java代码来实现。 P/Invoke是.NET平台的机制。而JNA是Java平台上的一个开源类库,和其他类库没有 什么区别。只需要在classpath下加入jna.jar包,就可以使用JNA。 JNA使Java平台可以方便地调用原生函数,这大大扩展了Java平台的整合能力。

2 新建项目,添加依赖

快速搭建一个springboot 项目,在pom文件中加入

net.java.dev.jna jna 4.5.1 com.sun.jna jna 3.0.9

3 Java 代码调用

首先看dll文件中定义的函数

//dll 文件中初始化函数 int INIT(char * pErrMsg)

新建一个类,类中新增下面接口 ,SiInterface 为dll文件,可以去掉后缀.dll

public interface SiInterface extends Library { // DLL文件默认路径为项目根目录,若DLL文件存放在项目外,请使用绝对路径。(此处:(Platform.isWindows()?"SiInterface":"c")指本地动态库msvcrt.dll) SiInterface INSTANCE = (SiInterface) Native.loadLibrary( "SiInterface.dll", SiInterface.class); // 声明将要调用的DLL中的方法 public int INIT(byte[] input); }

main方法测试

public static void main(String[] args) throws Exception { //INIT函数,参数是一个char*类型的可读写参数,需要用byte[]类型 byte[] outData = new byte[2048]; int code = SiInterface.INSTANCE.INIT(outData); System.out.println(code); String result = Native.toString(outData,"gbk"); System.out.println(result); }

至此,调用dll的编码工作已经完成,是不是很简单 ,这都是sun公司大佬写的jna框架好用,但实战中其实会出现一些问题,下面总结一下

问题总结:

1 :java jna 报错:Unable to load library

这个错真让人头大,这个错误很明显是无法加载到指定的动态链接库,但是为什么无法加载确没有具体显示出来,是路径不对呢,还是dll的平台与当前jvm的平台不匹配没有在错误信息中显示出来。所以需要一步一步排除找原因。

 1)首先你要明确知道这个dll动态链接库是32位的还是64位的编译的,与之对应的就是你的java版本也是要对应的32位或者64位的。

 2)确认了第一点那么基本的环境就没问题了,然后是填写路径,一般路径可以是填相对路径还是绝对路径,为了避免可能出现未知错误,强烈建议还是填写绝对路径,绝对路径要是反斜杠"\",为了避免出错可以直接在IDE工具里面找到对应的dll文件右键copy path

java 动态加载jar中的方法 java jna 加载动态库_绝对路径

粘贴到加载dll路径的方法里作为参数,效果如下图2.2

java 动态加载jar中的方法 java jna 加载动态库_绝对路径_02

3)前面两步如果可以保证正确的话,那么基本上是可以加载成功的,如果还是失败那请再回去验证前面的步骤,如验证j程序运行是不是在你预期的jvm之上

点击运行程序看看当前运行的jdk版本是哪一个,如下图3.1

java 动态加载jar中的方法 java jna 加载动态库_java_03

              图3.1 

接下来就是cmd,运行java  -version,看下图3.2所示的jdk版本是32位,未显示默认32位的,还是64位。jdk版本一致,且是64位,那么与我的dll是相同的平台,

java 动态加载jar中的方法 java jna 加载动态库_java 动态加载jar中的方法_04

那么可以验证下dll是不是64位或者32位就好了

最后就是路径问题了,如果你是按照我的操作来的那么路径就不会有问题,应该是正常运行的。

  4)到这一步,你的程序还是无法加载dll文件的话,我只能提供思路就是,你的dll是否还引用了其它的dll文件,其它的dll文件的平台与当前不一致。或者找你得到dll来源,确认这个dll是否可以用,dll文件时可以用visual studio 2017或其它把版本工具用C#代码直接引用调用的,当然你也可以用哪个工具打包一个dll。

查看dll文件位数还有一个简便方法(当然可以问提供dll文件之人最快,人家开发的嘛):

用txt或notepad 以记事本的方式打开,乱码没关系,如果第二段PE 后面那个为L ,则是32位的,否则为64位 ,

java 动态加载jar中的方法 java jna 加载动态库_java_05

 最后总结一下:1.平台要一致,平台要一致,平台要一致,重要的事情说三遍。

       2.路径问题,最好是绝对路径。

剩下就是接口业务问题, 等待你的又是漫长的调试。。。。。。。

 

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3