android stduio 下NDK 开发规则介绍
一、类型转换表格
表1-1 基础数据类型的转换关系表
| Java | Native类型 | 符号属性 | 字长 |
|---|---|---|---|
| boolean | jboolean | 无符号 | 8位 |
| byte | jbyte | 无符号 | 8位 |
| char | jchar | 无符号 | 16位 |
| short | jshort | 有符号 | 16位 |
| int | jint | 有符号 | 32位 |
| long | jlong | 有符号 | 64位 |
| float | jfloat | 有符号 | 32位 |
| double | jdouble | 有符号 | 64位 |
表1-2 Java引用数据类型的转换关系表
| Java引用类型 | Native类型 | Java引用类型 | Native类型 |
|---|---|---|---|
| All objects | jobject | char[] | jcharArray |
| java.lang.Class | jclass | short[] | jshortArray |
| java.lang.String | jstring | int[] | jintArray |
| Object[] | jobjectArray | long[] | jlongArray |
| boolean[] | jbooleanArray | float[] | jfloatArray |
| byte[] | jbyteArray | double[] | jdoubleArrray |
| java.lang.Throwable | jthrowable |
二、常用类型介绍
2.1 JNIEnv结构体介绍
JNIEnv是一个与线程相关的代表JNI环境的结构体,图2-1展示了JNIEnv的内部结构:
图 2-1 JNIEnv 内部结构图
从上图可知,JNIEnv提供了一些JNI系统函数,通过这些函数能够操作jobject对象和调用java层的函数
2.2 用于操作java类的成员变量和成员函数的两个函数分别是:
jfieldID GetFieldID(jclass clazz,const char *name,const char *sig);
jmethodID GetMethodID(jclass clazz,const char *name,const char *sig);
其中,jclass代表Java类,name表示成员函数或者成员变量的名字,sig为参数类型+返回值信息
2.3 调用Java对象的函数和获取对象字段
NativeType Call<type>Method(JNIEnv *env,jobject obj,jmethodID methodID,...)
其中type是Java函数的返回值类型,NativeType是本地对应的返回值类型
NativeType Get<type>Field(JNIEnv *env,jobject obj,jfieldID fieldID)
void Set<type>Field(JNIEnv *env,jobject obj,jfieldID fieldID,NativeType value)
其中type和NativeType与上述一样,这里的jfieldID就是从上面的GetFieldId中找到的。
表2-1 常用的Get/Set方法
| Get方法 | Set方法 |
|---|---|
| GetObjectField | SetObjectField |
| GetBooleanField | SetBooleanField |
| GetByteField | SetByteField |
| GetCharField | SetCharField |
| GetShortField | SetShortField |
| GetIntField | SetIntField |
| GetLongField | SetLongField |
| GetFloatField | SetFloatField |
| GetDoubleField | SetDoubleField |
2.4 JNI类型签名介绍
先来看一段动态注册的代码,如果要了解动态注册的相关内容可以到
这里
static JNINativeMethod gMethods[]={
"stringFromJNI", //java层的函数名
"()Ljava/lang/String;", //(参数类型) 返回值类型,即JNI函数签名
(void *)stringFromJNI //本地库对应的函数名
}
这个数组中的第二个参数正是我们需要了解的
本例对应的java函数为 String stringFromJNI()
对应的JNI签名为
()Ljava/lang/String;
括号内是参数类型的标识,最右边是返回值类型的标识,
返回类型是引用类型时,其格式为 “L包名;”,上述例子的Ljava/lang/String;表示是一个Java String 类型
表2-2 类型标识示意表
| 类型标识 | Java类型 | 类型标识 | Java类型 |
|---|---|---|---|
| Z | boolean | F | float |
| B | byte | D | double |
| C | char | L/java/lang/String; | String |
| S | short | [I | int[] |
| I | int | [L/java/lang/object; | Object[] |
| J | long |
请初一,如果java类型是数组,则标识中会有一个 “[”,引用类型的标识最后都有一个 “;”
表2-3 函数签名的小例子
| 函数签名 | Java函数 |
|---|---|
| “()Ljava/lang/String;” | String f() |
| “(Ljava/lang/String;I)J | long f(String i,int c) |
| “([B)V” | void f(byte[] bytes) |
本文介绍了Android Studio下NDK开发的基本规则,包括基础数据类型和引用数据类型的转换关系,JNIEnv结构体及其提供的JNI系统函数,操作Java类成员变量和成员函数的方法,以及JNI类型签名的详细解释。
373

被折叠的 条评论
为什么被折叠?



