JNA的应用

  一、了解JNA之前,我们先了解一下JNA的前身JNI(Java Native Interface):通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植。 [1]  从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。

  实现流程:

  

  注意jni的编写命名是有要求的,这里可以参考:https://baike.baidu.com/item/JNI/9412164?fr=aladdin#书写步骤

  二、JNA(Java Native Access):提供一组Java工具类用于在运行期间动态访问系统本地库(native library:如Window的dll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标native library的函数与结构,JNA将自动实现Java接口到native function的映射。

  简而言之,就是jna基于jni的方式封装了很多api,在使用上面相对于jni来说简化了很多。

  实现流程:

  

  三、JNA的例子:

  1)编写c源码(sum.cpp)

extern "C" {
    int sum(int x, int y) {
        return x + y;
    }
}

   2)装换成*.dll/*.so文件

  windows

gcc -shared -o <dll_name> <c_name>

  linux

gcc -fpic -shared -o <so_name> <c_name>

  注意:windows环境中,使用windows的c环境导包,名称可以随便取,用dll的文件格式。linux中使用linux的c环境打包,以lib(name).so的方式命名。

  3)目录结构

  

   4)maven依赖(pom.xml)

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

  5)实现过程

package com.cetc.util;

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

import java.io.File;

public class SumUtil {

    public interface Sum extends Library {

        int sum(int x, int y);

        Sum INSTANCE = (Sum) Native.loadLibrary("sum", Sum.class);
    }

    static {
        File file = new File("src/main/resources/lib/sum.dll");
        System.load(file.getAbsolutePath());
    }

    public static void main(String[] args) {
        System.out.println("***************************");
        System.out.println(Sum.INSTANCE.sum(1,2));
        System.out.println("***************************");
    }
}

  6)测试效果

  

  四、总结:JNA在很大程度上面简化了不同语言之间的连接,通过动态库的方式,来提供给Java调用。使用场景一般用于性能要求比较高的场景,比如opencv等。

    注意:在实际开发工程中,不能直接把dll/so文件打入jar,因为System.load,加载的是绝对路径,可以放入Java的include.或者使用assembly的打包方式等。

   五、源码:https://github.com/lilin409546297/JNA

原文地址:https://www.cnblogs.com/ll409546297/p/11534886.html