JNI介绍

Android FFmpeg专题结构

1 JNI定义

JNI(Java Native Interface),即Java本地接口,JNI是Java调用Native 语言的一种特性。通过JNI可以使得Java与C/C++机型交互.

以下是oracle对JNI的定义
JavaTM Native Interface (JNI) is a standard programming interface for writing Java native methods and embedding the JavaTM virtual machine* into native applications. The primary goal is binary compatibility of native method libraries across all Java virtual machine implementations on a given platform.

更多oracle关于JNI的介绍可以参考 Java 原生接口规范

2 JNI介绍

Java语言的执行环境是Java虚拟机(JVM),JVM其实是主机环境中的一个进程,每个JVM虚拟机都在本地环境中有一个JavaVM结构体,该结构体在创建Java虚拟机时被返回,在JNI环境中创建JVM的函数为JNI_CreateJavaVM。

Native code通过JNI Function来访问Java VM的功能. JNI Function可以通过接口指针JNIEnv*来访问, 该指针指向一个指针数组,每个指针指向一个接口函数。 每个接口函数都在数组内的预定义偏移处。下图说明了接口指针的组织。

JNI介绍_第1张图片
designa.gif

3 JavaVM 和 JNIEnv

JNI 定义了两个关键数据结构,即“JavaVM”和“JNIEnv”。两者本质上都是指向函数表的二级指针。

  • JavaVM
    理论上,每个进程可以有多个 JavaVM,但 Android 只允许有一个。JavaVM中封装的这些函数指针主要是对JVM操作接口.比较常用的是使用 AttachCurrentThread()来获取JNIEnv结构体.
    JavaVM的获取方式:
    第一种方式,在加载动态链接库的时候,JVM会调用JNI_OnLoad(JavaVM* jvm, void* reserved)(如果定义了该函数)。第一个参数会传入JavaVM指针。
    第二种方式,在native code中调用JNI_CreateJavaVM(&jvm, (void*)&env, &vm_args)可以得到JavaVM指针。
    可以用全局变量,比如JavaVM
    g_jvm来保存获得的指针以便在任意上下文中使用。
    在C和C++中的JavaVM的定义有所不同,在C中JavaVM是JNIInvokeInterface_类型指针,而在C++中有对JNIInvokeInterface_进行了一次封装

  • JNIEnv
    JNIEnv提供了大部分 JNI 函数。原生函数第一个参数就是JNIEnv 。JNIEnv是当前Java线程的执行环境,因此,无法在线程之间共享 JNIEnv。如果一段代码无法通过其他方法获取自己的 JNIEnv,应该共享相应 JavaVM,然后使用 GetEnv 发现线程的 JNIEnv(关于线程在下一篇文章里面介绍)。开发者可以通过JNIEnv调用Java函数和操作Java代码

4 jobject与jclass类型

jobject与jclass通常作为JNI函数的第二个参数,当所声明Native方法是静态方法时,对应参数类型jclass,因为静态方法不依赖对象实例,而依赖于类,所以参数中传递的是一个jclass类型。如果声明的Native方法时非静态方法时,那么对应参数是jobject。

5 JNI数据类型

基本数据类型

Java类型 JNI类型 描述
boolean jboolean unsigned 8 bits
byte jbyte signed 8 bits
char jchar unsigned 16 bits
short jshort signed 16 bits
int jint signed 32 bits
long jlong signed 64 bits
float jfloat 32 bits
double jdouble 64 bits
void void N/A

引用数据类型

Java类型 JNI类型 描述
Object jobject 任何Java对象
class jclass class对象
String jstring 字符串对象
Object[] jobjectArray 对象数组
boolean[] jbooleanArray 布尔类型数组
char[] jbyteArray 字符数组
int[] jintArray int数组
long[] jlongArray long数组
float[] jfloatArray float数组
double[] jdoubleArray double数组
Throwable jthrowable
JNI介绍_第2张图片
types4.gif

参考
https://www.jianshu.com/p/87ce6f565d37
https://developer.android.google.cn/training/articles/perf-jni

你可能感兴趣的:(JNI介绍)