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) |