当前位置: 首页 > news >正文

如何快速使用JNI

文章目录

    • 1_JNI是什么?
    • 2_使用
    • 3_扩展

1_JNI是什么?

JNI 是Java Native Interface的缩写,通过JNI,允许Java代码与其他语言(通常是C或C++)编写的本地应用程序或库进行交互。简而言之就是,Java可以通过JNI调用C 或 C++ 语言写的代码。

2_使用

1、首先,准备一个demo让我们进行JNI的快速入门使用:

/*** @author shenyang* @version 1.0* @info JNI* @since 2024/6/29 下午5:03*/
public class JNIDemo {public static void main(String[] args) {System.out.println(System.getProperty("java.library.path"));System.out.println(add(1,2));}
}

2、需要将C/C++实现的方法用native关键字声明。

  • native关键字声明的方法我们就不需要给出方法体了,直接给出声明就好了。
public static native int add(int a, int b);//这个方法的作用是将两个整型相加

3、加载动态链接库(windows.dll为后缀,linux上.so为后缀名),通常是使用静态代码块来进行导入。

  • 使用 System对象的 public static void loadLibrary(String libname)方法不需要后缀,只要(库所在路径加上)库名。
static {System.loadLibrary("jniDemo");
}

4、使用 javac -hjavah生成.h为后缀的头文件

  • 注意:jdk10之后将javah这一命令移除了,JEP313: 移除JDK中附带的javah工具。
  • 注意下面第一个参数是存放到当前路径下(./
javac -h ./ JNIDemo.java
  • 生成的头文件JNIDemo.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h> //这个头文件在jdk/include/下
/* Header for class JNIDemo */#ifndef _Included_JNIDemo
#define _Included_JNIDemo
#ifdef __cplusplus
extern "C" {
#endif
/** Class:     JNIDemo 说明这个方法是在哪个类里* Method:    add     对应的是java中的add方法* Signature: (II)I	  括号里两个II表示第一个参数和第二个参数都是int类型,括号后面的I表示这个方法的返回值是int类型* 下面这部分是C++需要实现的函数声明*/
JNIEXPORT jint JNICALL Java_JNIDemo_add(JNIEnv *, jclass, jint, jint);#ifdef __cplusplus
}
#endif
#endif

下面这部分是C++需要实现的函数声明:

 //方法名就是Java(表示java的jni来调用的)_JNIDemo(方法属于的类的名称)_add(方法名)
JNIEXPORT jint JNICALL Java_JNIDemo_add(JNIEnv *, jclass, jint, jint);

5、根据生成的头文件里的函数声明实现对应的函数,创建JNIDemo.cpp文件。

  • 注意:下面的代码包含了之前生成的头文件JNIDemo.h,还需要其他头文件也可以一并包含进去,比如:iostream
  • 下面四个参数:JNIEnv *是一个指针封装了一些JNI的操作在里面,jclass参数也用不到只放一个参数类型就行了,后面两个参数因为用的到所以把参数名加上。
  • 函数的最终目的是返回a+b,再加上一些其他操作我们进行测试;
#include "JNIDemo.h"
#include <iostream>JNIEXPORT jint JNICALL Java_JNIDemo_add(JNIEnv *, jclass , jint a, jint b)
{std::cout <<"a = "<< a<<"	b= "<< b <<std::endl;return a+b;
}

6、将上面的cpp文件编译成动态链接库。

给对C++不太了解的同学解释下下面命令的意义:

  • -o jniDemo.dll: 指定输出文件的名称为jniDemo.dll(与System.loadLibrary("jniDemo")中保持统一)。在Windows系统上,动态链接库通常以.dll为扩展名。

  • -fPIC: 表示生成位置无关代码(Position-Independent Code)。这是生成共享库时常用的选项,使得生成的代码在加载到内存中的任何位置时都可以正确运行。

  • -shared: 指定生成一个共享库(动态链接库),而不是可执行文件。

  • -I: 包含路径选项,用于指定头文件所在目录。在这里,包含了特定于Windows系统的Java头文件。

  • JNIDemo.cpp: 源文件名,包含了具体的JNI方法实现。

  • 如果windows电脑上使用不了g++命令,那么可以下载MinGWX64 - x86_64-win32-sjlj。

g++ -o jniDemo.dll -fPIC -shared -I"E:\shenyang\.jdks\jdk-1.8\include\win32" -I"E:\shenyang\.jdks\jdk-1.8\include" JNIDemo.cpp

执行完毕后发先目录下出现jniDemo.dll文件:

在这里插入图片描述

最后运行 JNIDemo.java ,查看运行结果:

在这里插入图片描述

3_扩展

基础数据类型对应表:

Java 类型JNI 类型C/C++ 类型描述
booleanjbooleanunsigned char布尔类型,值为truefalse ,使用0表示false,非0表示true
bytejbytesigned char8位有符号整数
charjcharunsigned short16位无符号Unicode字符
shortjshortshort16位有符号整数
intjintint32位有符号整数
longjlonglong long64位有符号整数
floatjfloatfloat32位单精度浮点数
doublejdoubledouble64位双精度浮点数
voidvoidvoid无类型

引用数据类型对应表:

Java 类型JNI 类型描述
StringjstringJava字符串
Objectjobject任意Java对象
ClassjclassJava类
ThrowablejthrowableJava异常对象
boolean[]jbooleanArray布尔型数组
byte[]jbyteArray字节型数组
char[]jcharArray字符型数组
short[]jshortArray短整型数组
int[]jintArray整型数组
long[]jlongArray长整型数组
float[]jfloatArray单精度浮点型数组
double[]jdoubleArray双精度浮点型数组
任意类型的对象数组jobjectArray对象数组
Java数组中的任意类型jarray通用数组类型

相关文章:

  • Docker在windows上使用vscode远程连接容器
  • 23种设计模式【创建型模式】详细介绍之【单例模式】
  • LabVIEW项目外协时选择公司与个人兼职的比较
  • 工业路由器与家用路由器的区别
  • 4、音视频封装格式---FLV
  • 深度学习之半监督学习:一文梳理目标检测中的半监督学习策略
  • IT专业入门,高考假期预习指南
  • 浅谈前置处理器之用户参数
  • 一文学会LVS:概念、架构、原理、搭建过程、常用命令及实战案例
  • 基于Java微信小程序小说阅读系统设计和实现(源码+LW+调试文档+讲解等)
  • 使用 Vue 实现包含单选框的弹窗功能(附Demo)
  • 苹果公司的Wifi定位服务(WPS)存在被滥用的风险
  • GPIO和PIN
  • 用户想知道数据库每天增长几个G,到底都是啥?
  • Jmeter 入门指南:从零开始学习
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • github从入门到放弃(1)
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • js面向对象
  • markdown编辑器简评
  • quasar-framework cnodejs社区
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • TCP拥塞控制
  • 好的网址,关于.net 4.0 ,vs 2010
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 如何实现 font-size 的响应式
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 提醒我喝水chrome插件开发指南
  • 责任链模式的两种实现
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 大数据全解:定义、价值及挑战
  • 第二十章:异步和文件I/O.(二十三)
  • ​业务双活的数据切换思路设计(下)
  • #162 (Div. 2)
  • (175)FPGA门控时钟技术
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (学习日记)2024.01.19
  • (译) 理解 Elixir 中的宏 Macro, 第四部分:深入化
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .Family_物联网
  • .NET CF命令行调试器MDbg入门(二) 设备模拟器
  • .net FrameWork简介,数组,枚举
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉
  • .NET和.COM和.CN域名区别
  • .NET性能优化(文摘)
  • [ JavaScript ] JSON方法
  • [ vulhub漏洞复现篇 ] Jetty WEB-INF 文件读取复现CVE-2021-34429
  • [ 云计算 | AWS 实践 ] Java 如何重命名 Amazon S3 中的文件和文件夹
  • [202209]mysql8.0 双主集群搭建 亲测可用
  • [Android] Amazon 的 android 音视频开发文档