由于引用类型以不透明的方式传递给原生代码,因此引用类型不能直接使用和修改。但JNI提供了一些操作应用类型的API
本文主要介绍
- 字符串
- 数组
- NIO缓冲区
- 字段
- 方法
基本数据类型
引用类型
1.创建字符串
jstring javaString;
javaString = (*env)->NewString(env,"HelloWorld");//创建Unicode字符串
javaString = (*env)->NewStringUTF(env,"HelloWorld");//创建UTF字符串
2.把Java字符串转换成C字符串
在原生代码中使用Java字符串需要先将其转换为C字符串
const jbyte* str;
jboolean isCopy;
str = (*env)->GetStringChars(env,javaString,&isCopy);//获得Unicode字符串
//GetStringUTFChars(env,javaString,&isCopy)//获得UTF字符串
if(str != 0){
}
//isCopy参数是一个可选参数,让调用者确定C字符串是指向副本还是堆中的固定对象。可选是 JNI_TRUE ,JNI_FALSE
3.释放字符串
JNI需要显式释放内存
(*env)->ReleaseStringChars(env,javaString,str);//Unicode
(*env)->ReleaseStringUTFChars(env,javaString,str);//UTF
4.数组
New< Type>Array Type可以使Int ,String ,Boolean ,Char
jintArray javaArray;
javaArray = (*env)->NewIntArray(env,10);//创建数组
jint nativeArray(10);
(*env)->GetIntArrayRegion(env,javaArray,0,10,nativeArray);//将java数组复制到给定的C数组中
(*env)->SetIntArrayRegion(env,javaArray,0,10,nativeArray);//将c数组复制回Java数组中
jint* nativeDirectArray;
jboolean isCopy;
nativeDirectArray = (*env)->GetIntArrayElements(env,javaArray,&isCopy);// 对直接指针操作
(*env)->ReleaseIntArrayElements(env,javaArray,nativeDirectArray,0);
// 第四个参数
// 0 复制内容,并释放原生数组
// JNI_COMMIT 复制内容,但不释放原生数组
// JNI_ABORT 释放原生数组,但不用复制内容
5.NIO操作
5.1创建直接字节缓冲区
unsigned char* buffer = (unsigned char*) malloc (1024);
jobject directBuffer;
directBuffer = (*env)->NewDirectByteBuffer(env,Buffer,1024);
5.2直接字节缓冲区获得
usigned char* buffer;
buffer = (unsigned char*)(*env)->GetDirectBufferAddress(env,directBuffer);
5.3访问域
jclass clazz;
clazz = (*env)->GetObjectClass(env,instance);//获得类
获得实例域ID
jfieldID instanceFieldId;
instanceFieldId = (*env)->GetFieldID(env,clazz,"instanceField","Ljava/lang/String;");
获得静态域ID
jfieldID staticFieldId;
staticFieldId = (*env)->GetStaticFieldID(env,clazz,"staticField","Ljava/lang/String;")";
获取实例域
jstring instanceField;
instanceField = (*env)->GetObjectField(env,instance,instanceFieldId);
获取静态域
jstring staticField;
staticField = (*env)->GetStaticObjectField(env,clazz,staticFieldId);
6.调用方法
获取实例方法ID
jmethodID instanceMethodId;
instanceMethodId = (*env)->GetMethodID(env,clazz,"instanceMethod","()Ljava/lang/String;");
获取静态方法ID
jmethodID staticMethodId;
staticMethodId = (*env)->GetStaticMethodID(env,clazz,"staticMethod","()Ljava/lang/String;");
调用实例方法
jstring instanceMethodResult;
instanceMethodResult = (*env)->CallStringMethod(env,instance,instanceMethodId);//调用实例方法
jstring staticMethodResult;
staticMethodResult = (*env)->CallStaticStringMethod(env,clazz,staticMethodId);