JNI技术简介

65 篇文章 0 订阅
61 篇文章 1 订阅
JNI技术允许Java代码调用C/C++库,提高性能。JNI函数通过接口指针实现交互,静态注册需遵循命名规范,动态注册性能更优。JNI数据类型转换涉及基础和引用类型,方法签名用于解决重载问题。本地方法注册包括静态和动态两种方式,其中动态注册避免了冗长的函数名,并提高了执行效率。
摘要由CSDN通过智能技术生成

JNI技术

**目标:**认识JNI(Java Native Interface)技术,了解Java调用本地C/C++库的简单原理以及一些基本的知识点

一、简介

JNI是Java Native Interface的缩写,通过使用Java本地接口书写程序,可以确保代码在不同的平台上方便移植。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。

本地代码与 Java 虚拟机之间是通过 JNI 函数实现相互操作的。JNI函数通过接口指针来获得,本地方法将 JNI 接口指针当作参数来接受。虚拟机保证在从相同的 Java 线程中对本地方法进行多次调用时,传递给本地方法的接口指针是相同的,本地方法被不同的 Java 线程调用时,它接受不同的 JNI接口指针

使用JNI和算法进行交互,主要是为了提高算法的性能,最大化的利用机器硬件资源

二、JNI技术原理

**(1)**提供一种Java字节码调用C/C++的解决方案,JNI描述的是一种技术。

native代码想要访问 java虚拟机需要调用JNI方法,而获取JNI方法则通过 JNI interface Pointer。它实际指向的就是一个都是指针的数组,每个指针指向的都是一个接口函数,接口函数可以使用C/C++等实现

优势:

JNI 命名和native code书写分开,避免硬编码

JNI interface Pointer 只在当前线程有效,即native 方法不能在线程之间传递(不同线程的指针可能不一样),VM保证同一个线程中调用多次JNI interface Pointer是同一个

(2)JNI方法注册:

**静态注****册:**可参考JNI调用C/C++接口示例

当Java层调用navtie函数时,会在JNI库中根据函数名查找对应的JNI函数。如果没找到,会报错。如果找到了,则会在native函数与JNI函数之间建立关联关系,其实就是保存JNI函数的函数指针。下次再调用native函数,就可以直接使用这个函数指针。

JNI函数名格式:

Java_ + 包名(com_example_auto_jnitest)+ 类名(MainActivity) + 函数名(stringFromJNI)

静态方法的缺点:

要求JNI函数的名字必须遵循JNI规范的命名格式;

名字冗长,容易出错;

初次调用会根据函数名去搜索JNI中对应的函数,会影响执行效率;

需要编译所有声明了native函数的Java类,每个所生成的class文件都要用javah工具生成一个头文件

动态注册:

通过提供一个函数映射表,注册给JVM虚拟机,这样JVM就可以用函数映射表来调用相应的函数,就不必通过函数名来查找需要调用的函数。

Java与JNI通过JNINativeMethod的结构来建立函数映射表,它在jni.h头文件中定义,其结构内容如下:

typedef struct {
const char* name;
const char* signature;
void* fnPtr;
} JNINativeMethod;

创建映射表后,调用RegisterNatives函数将映射表注册给JVM;

当Java层通过System.loadLibrary加载JNI库时,会在库中查JNI_OnLoad函数。可将JNI_OnLoad视为JNI库的入口函数,需要在这里完成所有函数映射和动态注册工作,及其他一些初始化工作。

优点:

函数名简单

初次调用相比于静态注册性能好

(3)JNI数据类型转换与方****法签名

基础数据类型转换:

引用数据类型转换:

除了Class、String、Throwable和基本数据类型的数组外,其余所有Java对象的数据类型在JNI中都用jobject表示。Java中的String也是引用类型,但是由于使用频率较高,所以在JNI中单独创建了一个jstring类型。

引用类型不能直接在 Native 层使用,需要根据 JNI 函数进行类型的转化后才能使用;多维数组(含二维数组)都是引用类型,需要使用 jobjectArray 类型存取其值;

例如,二维整型数组就是指向一维数组的数组,其声明使用方式如下:

//获得一维数组的类引用,即jintArray类型
jclass intArrayClass = env->FindClass(“[I”);
//构造一个指向jintArray类一维数组的对象数组,该对象数组初始大小为length,类型为 jsize
jobjectArray obejctIntArray = env->NewObjectArray(length ,intArrayClass , NULL);

JNI方法签名

格式为:(形参参数类型列表)返回值。

由于Java支持函数重载,因此仅仅根据函数名是没法找到对应的JNI函数。为了解决这个问题,JNI将参数类型和返回值类型作为函数的签名信息。

例如:

JNI常用的数据类型及对应字符

先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值