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

香菜聊游戏 发表于 2022/06/26 21:33:17 2022/06/26
【摘要】 “持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情”jna 是什么JNA = Java Native Access是基于JNI开发的一个框架。是为了降低JNI 开发的复杂性的一个Java框架。可以不用写c/c++ 代码调用动态库。JNA 开源项目的信息SUN公司主导开发的开源项目 github地址 :github.com/java-native…...

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

“持续创作,加速成长!这是我参与「掘金日新计划 · 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

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。