JNI之函数介绍一

NDK2023年7月22日 am8:08发布1年前 (2023)更新 91es.com站长
42 0 0
目录

前言

虽然jni.h中定义了很多函数,但也不是每个都需要用,这个主要是看需求。今天介绍一下常用jni函数,方便自己后续查阅。

正文

每个个函数可通过JNIEnv指针以固定偏移量进行访问。JNIEnv指针可指向存储全部JNI函数指针的结构。

如果要看全部的函数定义,可以看《NDK中jni.h头文件完整内容》,这里只介绍常用的函数。

GetVersion

返回本地方法接口的版本。

jint        (*GetVersion)(JNIEnv *env);

仅一个参数,env是jni接口指针。

在C++中调用更简洁些,后续都以C++方法调用,不重复解释了。

jint version = env->GetVersion();
#打印十六进制
LOGE("GetVersion:%#x", version);

输出

GetVersion:0x10006

16 位返回主版本号,低 16 位返回次版本号

我这用的是jdk1.6。

FindClass

jclass      (*FindClass)(JNIEnv* env, const char* name);

该函数用于加载本地定义的类。搜索在由环境变量 CLASSPATH 目录下的子目录和zip文件中搜索指定的类名。

只关注第二个参数name,类全名 ,即包名后跟类名,之间由“ /” 分隔。如果名称以“ [” ( 数组签名字符)打头,则返回一个数组类 。

举些例子:

# String 的类全名(java.lang.String)
name = "Ljava/lang/String"

# Object[] 的类全名
name = "[Ljava/lang/Object;"

# 自定义Hello类
name = "com/biumall/dynamic/one/Hello"

如果存在,返回指定名称的类的对象,否则返回NULL。

存在如下异常:

  1. ClassFormatError:如果class内容不是一个有效的class文件。

  2. ClassCircularityError:如果class或interface是它自己的父类或父接口,造成循环层级关系。

  3. OutOfMemoryError:如果系统在载入的过程中内存不足

  4. NoClassDefFoundError`:如果指定的类或接口没有被找到。

GetSuperclass

jclass      (*GetSuperclass)(JNIEnv* env, jclass clazz);
  1. 如果clazz代表类而非类object,则该函数返回由clazz所指定的类的超类。

  2. 如果clazz指定类object或代表某个接口,则该函数返回 NULL 。

至于第二个参数表示clazz还是object的,可以看《JNI之函数的参数介绍》这篇。

这里总结一下,clazz在静态函数时是jcalss,非静态时是jobject。

IsAssignableFrom

jboolean    (*IsAssignableFrom)(JNIEnv* env, jclass clazz1, jclass clazz2);

判断clazz1的对象是否可安全地强制转换为clazz2。

如果是以下情况则返回 JNI_TRUE :

  • clazz1 和 clazz2 指向同一个java类

  • clazz1 是 clazz2 的子类。(向上转型是安全的)

  • clazz1 是 clazz2(接口)的实现类。(也属于向上转型)

Throw

jint Throw(JNIEnv *env, jthrowable obj);

触发一个 java.lang.Throwable 对象的异常被抛出。obj是java.lang.Throwable对象。

成功则返回0, 失败时返回负数。

抛出 java.lang.Throwable 对象。

jthrowable exception = env->ExceptionOccurred();
if (exception) {
  env->ExceptionClear();
  detach_internal(env, this_obj);
  env->Throw(exception);
  return;
}

ThrowNew

jint ThrowNew(JNIEnv *env, jclass clazz, const char *message);

Exception对象的构造器函数,message为异常的错误消息,clazz为异常的类。

clazz为java.lang.Throwable的子类。

message用于创建 java.lang.Throwable 对象时传入的错误消息。这个是字符串是UTF-8编码。

成功则返回0, 失败时返回负值。并抛出刚构造出来的 java.lang.Throwable对象。

env->ThrowNew(env->FindClass("sun/jvm/hotspot/debugger/DebuggerException"), errMsg);

其他的暂时不记录了,主要没常用。请看参考文3吧。多谢

参考文章

  1. JNI完全手册]》

  2. NDK中jni.h头文件完整内容

  3. JNI技术规范 - 第四章 JNI函数(1)》(后面几个函数的主要来源)

 历史上的今天

  1. 2021: 余秋雨:我在等你(0条评论)
  2. 2019: 郁达夫:北平的四季(0条评论)
版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com[备用域名]
3、 本站内容: 部分来源于网络,仅供站长学习和参考,若侵权请留言

暂无评论

暂无评论...

随机推荐

CPU缓存

前言本文简单的介绍一下CPU缓存相关知识。本文参考网络文章整理而成。正文CPU缓存简介CPU缓存(Cache Memory)是位于CPU与内存之间的临时存储器,它的容量比内存小的多但是交换速度却比内存要快得多。缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾,因为CPU运...

朱自清:神奇的丝瓜

今年春天,孩子们在房前空地上,斩草挖土,开辟出来了一个一丈见方的小花园。周围用竹竿扎了一个篱笆,移来了一棵玉兰花树,栽上了几株月季花,又在竹篱下面随意种上了几棵扁豆和两棵丝瓜。土壤并不肥沃,虽然也铺上了一层河泥,但估计不会起很大的作用,大家不过是玩玩而已。过了不久,丝瓜竟然长了出来,而且日益茁壮。...

手动更新wordpress版本

由于某些原因,WordPress 下载的网站无法打开,导致更新一直失败,因此只好手动更新。一:最新版本WordPress5.3.2中文版:https://downloads.wordpress.org/release/zh_CN/wordpress-5.3.2.zip二、手动更新在服务器里删...

余光中:绝色

美丽而善变的巫娘,那月亮翻译是她的特长却把世界译走了样 把太阳的鎔金译成了流银把烈火译成了冰而且带点薄荷的风味 凡尝过的人都说译文是全不可靠但比起原文来呢却更加神秘,更加美 雪是另一位唯美的译者存心把世界译错或者译对,诗人说只因原文本来就...

米沃什:去森林的远足

树木那么巨大,你看不见树梢。 落下的太阳收拢玫瑰色的光芒 在每棵树上,就像在烛台上面, 小小的人儿走在下面的路上。 让我们扬起头,拉着手 这样就不会在纠结的草丛迷路。 夜晚开始在花朵上加上封条, 色彩连着色彩飘下天空。 那里,上面,一次盛宴。金罐, 倒进了阿斯彭铜器的红酒。 一辆空中的车...

简单记录AIDL添加回调

前言之前也记录过AIDL的使用,今天简单写AIDL添加回调代码。记录一下,方便自己查阅。流水账,勿喷!正文为了简单一点,放在同一个应用中,然后把服务设置到新的进程中。AIDL文件设置回调,这里会创建两个AIDL文件。ICar.aidl// ICar.aidlpackage ...