NDK开发 - JNI数组数据处理
副标题[/!--empirenews.page--]
传送门:NDK开发 - JNI数组数据处理 JNI 中的数组分为基本类型数组和对象数组,它们的处理方式是不一样的,基本类型数组中的所有元素都是 JNI 的基本数据类型,可以直接访问。而对象数组中的所有元素是一个类的实例或其它数组的引用,和字符串操作一样,不能直接访问 Java 传递给 JNI 层的数组,必须选择合适的 JNI 函数来访问和设置 Java 层的数组对象。 访问基本类型数组Java 代码: //调用数组 byte array[] = {'A','B','C','D','E'}; byte[] resutl = NativeMethod.getByteArray(array); for (int i = 0; i < array.length; i++) { Log.d(TAG,"ARRAY : " + array[i] + "->" + resutl[i]); } native 代码: JNIEXPORT jbyteArray JNICALL Java_com_example_gnaix_ndk_NativeMethod_getByteArray (JNIEnv *env,jclass object,jbyteArray j_array){ //1. 获取数组指针和长度 jbyte *c_array = env->GetByteArrayElements(j_array,0); int len_arr = env->GetArrayLength(j_array); //2. 具体处理 jbyteArray c_result = env->NewByteArray(len_arr); jbyte buf[len_arr]; for(int i=0; i<len_arr; i++){ buf[i] = c_array[i] + 1; } //3. 释放内存 env->ReleaseByteArrayElements(j_array,c_array,0); //4. 赋值 env->SetByteArrayRegion(c_result,len_arr,buf); return c_result; } 运行结果: 示例中,从 Java 层中传进去了一个数组,参数类型是 byte[],对应 JNI 中 jbyteArray 类型。利用 除了上述方法还可以用 JNI 中的 JNIEXPORT jint JNICALL Java_com_example_gnaix_ndk_NativeMethod_getByteArray (JNIEnv *env,jbyteArray j_array){ jbyte *c_array; jint len_arr; //1. 获取数组长度 len_arr = env->GetArrayLength(j_array); //2. 申请缓冲区 c_array = (jbyte *) malloc(sizeof(jbyte) * len_arr); //3. 初始化缓冲区 memset(c_array,sizeof(jbyte)*len_arr); //4. 拷贝java数组数据 env->GetByteArrayRegion(j_array,c_array); //5. 计算总和 int sum = 0; for(int i=0; i<len_arr; i++){ sum += c_array[i]; } //6. 释放缓冲区 free(c_array); return sum; } 访问引用类型数组 JNI 提供了两个函数来访问对象数组,GetObjectArrayElement 返回数组中指定位置的元素,SetObjectArrayElement 修改数组中指定位置的元素。与基本类型不同的是,我们不能一次得到数据中的所有对象元素或者一次复制多个对象元素到缓冲区。因为字符串和数组都是引用类型,只能通过 Get/SetObjectArrayElement 这样的 JNI 函数来访问字符串数组或者数组中的数组元素。 //返回对象数组 Person persons[] = NativeMethod.getPersons(); for(Person person : persons){ person.toString(); } Person 类: /** * 名称: Person * 描述: * * @author xiangqing.xue * @date 16/3/10 */ public class Person { private String TAG = "Person"; public String name; public int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString(){ String result = "Name: " + name + ",age: " + age; Log.d(TAG,result); return result; } } Native 方法: JNIEXPORT jobjectArray JNICALL Java_com_example_gnaix_ndk_NativeMethod_getPersons (JNIEnv *env,jclass object){ jclass clazz = NULL; jobject jobj = NULL; jmethodID mid_construct = NULL; jfieldID fid_age = NULL; jfieldID fid_name = NULL; jstring j_name; //1. 获取Person类的Class引用 clazz = env->FindClass("com/example/gnaix/ndk/Person"); if(clazz == NULL){ LOGD("clazz null"); return NULL; } //2. 获取类的默认构造函数ID mid_construct = env->GetMethodID(clazz,"<init>","()V"); if(mid_construct == NULL){ LOGD("construct null"); return NULL; } //3. 获取实例方法ID和变量ID fid_name = env->GetFieldID(clazz,"name","Ljava/lang/String;"); fid_age = env->GetFieldID(clazz,"age","I"); if(fid_age==NULL || fid_name==NULL){ LOGD("age|name null"); return NULL; } //4. 处理单个对象并添加到数组 int size = 5; jobjectArray obj_array = env->NewObjectArray(size,clazz,0); for(int i=0; i<size; i++){ jobj = env->NewObject(clazz,mid_construct); if(jobj == NULL){ LOGD("jobject null"); return NULL; } env->SetIntField(jobj,fid_age,23 + i); j_name = env->NewStringUTF("gnaix"); env->SetObjectField(jobj,fid_name,j_name); env->SetObjectArrayElement(obj_array,i,jobj); } //5. 释放局部变量 env->DeleteLocalRef(clazz); env->DeleteLocalRef(jobj); return obj_array; } 运行结果: (编辑:青岛站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |