Java 使用JNA 调用dll动态库文件

 

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文件中加入

        <dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna</artifactId>
            <version>4.5.1</version>
        </dependency>


        <dependency>
            <groupId>com.sun.jna</groupId>
            <artifactId>jna</artifactId>
            <version>3.0.9</version>
        </dependency>

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

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

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

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

              图3.1 

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

那么可以验证下dll是不是64位或者32位就好了,验证方法自行百度或者参照这位博主的https://www.cnblogs.com/Czhenyu/p/6439383.html

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

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

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

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

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

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

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

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值