JNI基础:JNI数据类型和类型描述符

一、简介

    在 JNI 开发中,我们知道,Java 的数据类型并不是直接在 JNI 里使用的,例如 int 就是使用 jint 来表示。
那么,就如我们来认识一下这些数据类型吧。

 

二、基本数据类型

 Java数据类型

 JNI本地类型

 C/C++数据类型

数据类型描述 

 boolean

 jboolean

 unsigned char 

C/C++无符号8为整数 

 byte

 jbyte

 signed char 

C/C++有符号8位整数 

 char

 jchar 

 unsigned short 

C/C++无符号16位整数 

 short

 jshort 

 signed short

C/C++有符号16位整数 

 int

 jint 

 signed int 

C/C++有符号32位整数 

 long

 jlong

 signed long 

C/C++有符号64位整数 

 float

 jfloat 

 float 

C/C++32位浮点数 

 double

 jdouble 

 double 

C/C++64位浮点数 

 

三、引用数据类型

Java的类类型

 JNI的引用类型

 类型描述

 java.lang.Object

 jobject

 可以表示任何Java的对象,或者没有

JNI对应类型的Java

对象(实例方法的强制参数

 java.lang.String

 jstring

 Java的String字符串类型的对象

 java.lang.Class

 jclass

 Java的Class类型对象(静态方法的强制参数)

 Object[]

 jobjectArray

 Java任何对象的数组表示形式

 boolean[]

 jbooleanArray

 Java基本类型boolean的数组表示形式

 byte[]

 jbyteArray

 Java基本类型byte的数组表示形式

 char[]

 jcharArray

 Java基本类型char的数组表示形式

 short[]

 jshortArray

 Java基本类型short的数组表示形式

 int[]

 jintArray

 Java基本类型int的数组表示形式

 long[]

 jlongArray

 Java基本类型long的数组表示形式

 float[]

 jfloatArray

 Java基本类型float的数组表示形式

 double[]

 jdoubleArray

 Java基本类型double的数组表示形式

 java.lang.Throwable

 jthrowable

 Java的Throwable类型,表示异常的所有类型和子类

 void

 void

N/A

 

四、数据类型描述符

1. 什么是数据类型描述符

    在JVM虚拟机中,存储数据类型的名称时,是使用指定的描述符来存储,而不是我们习惯的 int,float 等。

2. 对照表

 Java类型

 类型描述符

 int

 I

 long

 J

 byte

 B

 short

 S

 char

 C

 float

 F

 double

 D

 boolean

 Z

void

V

 其他引用类型

 L+类全名+;

数组

[

方法

(参数)返回值

3. 示例

3.1 例如我们要表示一个 String 类

    Java 类型:java.lang.String
    JNI 描述符:Ljava/lang/String;
    即一个 Java 类对应的描述符,就是 L 加上类的全名,其中 . 要换成 / ,最后 不要忘掉末尾的分号

3.2 假如我们想要表示数组的话

    Java 类型:String[]
    JNI 描述符:[Ljava/lang/String;
    Java 类型:int[][]
    JNI 描述符:[[I
    数组就是简单的在类型描述符前加 [ 即可,二维数组就是两个 [ ,以此类推。

3.3 方法

    Java 方法:long f (int n, String s, int[] arr);
    JNI 描述符:(ILjava/lang/String;[I)J
    Java 方法:void f ();
    JNI 描述符:()V
    括号内是每个参数的类型符,括号外就是返回值的类型符。

 

其它:

​NDK 学习系列:Android NDK 从入门到精通(汇总篇)

  • 11
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是 JNI 中遍历 std::map 的示例代码: ```c++ JNIEXPORT void JNICALL Java_com_example_MapExample_mapIteration(JNIEnv *env, jobject obj, jobject mapObj) { // 获取 Map 的 class 对象 jclass mapClass = env->GetObjectClass(mapObj); // 获取 Map.entrySet() 方法的 ID jmethodID entrySetMethodID = env->GetMethodID(mapClass, "entrySet", "()Ljava/util/Set;"); // 调用 Map.entrySet() 方法获取所有的键值对 jobject entrySetObj = env->CallObjectMethod(mapObj, entrySetMethodID); // 获取 Set 的 class 对象 jclass setClass = env->GetObjectClass(entrySetObj); // 获取 Set.iterator() 方法的 ID jmethodID iteratorMethodID = env->GetMethodID(setClass, "iterator", "()Ljava/util/Iterator;"); // 调用 Set.iterator() 方法获取迭代器 jobject iteratorObj = env->CallObjectMethod(entrySetObj, iteratorMethodID); // 获取 Iterator 的 class 对象 jclass iteratorClass = env->GetObjectClass(iteratorObj); // 获取 Iterator.hasNext() 方法的 ID jmethodID hasNextMethodID = env->GetMethodID(iteratorClass, "hasNext", "()Z"); // 获取 Iterator.next() 方法的 ID jmethodID nextMethodID = env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;"); // 遍历 Map 中的所有键值对 while (env->CallBooleanMethod(iteratorObj, hasNextMethodID)) { // 调用 Iterator.next() 方法获取下一个键值对 jobject entryObj = env->CallObjectMethod(iteratorObj, nextMethodID); // 获取 Map.Entry 的 class 对象 jclass entryClass = env->GetObjectClass(entryObj); // 获取 Map.Entry.getKey() 方法的 ID jmethodID getKeyMethodID = env->GetMethodID(entryClass, "getKey", "()Ljava/lang/Object;"); // 获取 Map.Entry.getValue() 方法的 ID jmethodID getValueMethodID = env->GetMethodID(entryClass, "getValue", "()Ljava/lang/Object;"); // 调用 Map.Entry.getKey() 方法获取键 jstring keyObj = (jstring) env->CallObjectMethod(entryObj, getKeyMethodID); // 调用 Map.Entry.getValue() 方法获取值 jstring valueObj = (jstring) env->CallObjectMethod(entryObj, getValueMethodID); // 将键值转换为 C++ 字符串 const char* key = env->GetStringUTFChars(keyObj, NULL); const char* value = env->GetStringUTFChars(valueObj, NULL); // 输出键值对 printf("%s: %s\n", key, value); // 释放字符串所占用的内存 env->ReleaseStringUTFChars(keyObj, key); env->ReleaseStringUTFChars(valueObj, value); } } ``` 这段代码首先获取了 Map 对象的 class 对象,然后获取了 Map.entrySet() 方法的 ID,并调用该方法获取所有的键值对。接着获取了 Set 对象的 class 对象,以及 Set.iterator() 方法的 ID,并调用该方法获取迭代器。然后获取了 Iterator 对象的 class 对象,以及 Iterator.hasNext() 方法和 Iterator.next() 方法的 ID。最后通过迭代器遍历 Map 中的所有键值对,并获取每个键值对的键和值,将其转换为 C++ 字符串后输出。需要注意的是,遍历结束后需要释放字符串所占用的内存。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值