【混合编程jni 】第十篇之JNA初见

405 阅读2分钟

“持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情

jna 是什么

JNA = Java Native Access

是基于JNI开发的一个框架。

是为了降低JNI 开发的复杂性的一个Java框架。

可以不用写c/c++ 代码调用动态库。

JNA 开源项目的信息

SUN公司主导开发的开源项目 github地址 :github.com/java-native…

文档地址:github.com/java-native…

如果你想仔细的研究下这个项目,可以直接去读英文了,文章结束了🧨

如果你想先从简单的开始,那就跟着我一起先做个demo

举个例子

创建一个Maven项目 在pom.xml 中导入依赖

<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>5.3.1</version>
</dependency>
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna-platform</artifactId>
    <version>5.3.1</version>
</dependency>

下载提供的dll 如果你有C++的环境,可以自己创建一个动态链接库的项目

如果你没有,可以直接下载我提供的dll,下载地址:TODO

dll中提供一个简单的加法函数

dll中的文件内容如下,

#ifndef TESTJNA_TEST_H
#define TESTJNA_TEST_H
#define PDOOL_API extern "C" __declspec( dllexport )
PDOOL_API int sum(int a, int b);
#endif //TESTJNA_TEST_H
cpp 文件

#include "test.h"
int sum(int a ,int b){
    return a +b;
}

Java 测试代码

package org.pdool;
import com.sun.jna.Library;
import com.sun.jna.Native;
/**
 * 动态库接口
 * @author 香菜
 */
public interface Lib extends Library {
 
    Lib INSTANCE = Native.load( "testJNA.dll", Lib.class);
 
    int sum(int a,int b);
}
package org.pdool;
 
/**
 * Hello world!
 *
 */
public class App 
{
    public static void main(String[] args) {
        int result = Lib.INSTANCE.sum(1,3);
        System.out.print("恭喜,JNA 第一个程序成功 ,the  result is  "+ result);
    }
}

如果你自己的dll在其他位置,可以在运行的时候增加vm option,也就是dll 所在的地址

-Djava.library.path=D:\workspace\ba\TestJni\TestJNA\src\main\resources

image.png

看下执行结果,完美

image.png

JNA技术解析

再次看下核心代码

public interface Lib extends Library {
    //    将dll 加载 并将dll中的方法映射到当前接口
    Lib INSTANCE = Native.load( "testJNA.dll", Lib.class);
    //    C 侧的函数定义
    int sum(int a,int b);
}

对于Java侧的程序来说,只要写这么一个接口就行了

常见一个静态变量持有当前动态库

下面就是C侧提供的函数定义,直接调用就行,

更没有JNI的一堆什么烦人的方法签名,

更不用担心不会C++

是真的方便

注意的问题

如果自己创建C++ 项目,要注意编译的选项要和Java的保持一致,我的都是64位的 注意保持函数名和动态库的函数一致 注意dll 的位置,放到java.library.path 的环境变量内,或者直接加入系统的查找路径 搜索dll的路径是:

1)项目的根路径,resource首层

2)操作系统的全局路径、system32

3)path指定的路径,java.library.path