如何使用JNI传递和接收对象

我有一个JAVA应用程序,我希望使用JNI将对象作为参数传递给C代码,并且我想再次使用JNIC代码接收对象到JAVA

在JAVA方面,我只是创建了一个应用程序并将其传递给方法,如下所示

 JlibFprint.fp_image_data fpimg = new JlibFprint.fp_image_data(); //object to be pass //fp_image_data is the static inner class of the class JlibFprint JlibFprint.fp_image_data fpimg1 = new JlibFprint.fp_image_data(); //received object 

这个对象传递给像这样的方法

 fpimg1 = JlibFprint.binary_image(fpimg); 

该方法的JNI代码如下所示:

 JNIEXPORT jobject JNICALL Java_jlibfprint_JlibFprint_binary_1image(JNIEnv *env, jclass jcls,jobject imgobj) { struct fp_img img; struct fp_img *imgptr; imgptr = &img; jfp2cfp(env,imgobj,imgptr); fp_init(); imgptr = fp_img_binarize(imgptr); cfp2jfp(env, imgobj, imgptr); fp_exit(); return imgobj; } void jfp2cfp(JNIEnv* env, jobject obj, fp_img *fpd) { /* Determines all the fields of the object */ jclass fpClass = env->FindClass("jlibfprint/JlibFprint$fp_image_data"); jfieldID height; jfieldID width; jfieldID length; jfieldID data; jbyteArray dataArray; height = env->GetFieldID(fpClass, "height", "I"); width = env->GetFieldID(fpClass, "width", "I"); length = env->GetFieldID(fpClass, "length", "I"); data = env->GetFieldID(fpClass, "data", "[B"); /* Starts to fill fpd */ fpd->height = env->GetIntField(obj, height); fpd->width = env->GetIntField(obj, width); fpd->length = env->GetIntField(obj, length); printf("\n height :%d",fpd->height); printf("\n width :%d",fpd->width); printf("\n length :%d",fpd->length); dataArray = static_cast(env->GetObjectField(obj, data)); env->GetByteArrayRegion(dataArray, 0, FP_PRINT_DATA_DATA_SIZE, (jbyte*)fpd->data); } void cfp2jfp(JNIEnv* env, jobject obj, fp_img* fpd) { /* Determines all the fields of the object */ jclass fpClass = env->FindClass("jlibfprint/JlibFprint$fp_image_data"); jfieldID height; jfieldID width; jfieldID length; jfieldID data; jbyteArray dataArray; height = env->GetFieldID(fpClass, "height", "I"); width = env->GetFieldID(fpClass, "width", "I"); length = env->GetFieldID(fpClass, "length", "I"); data = env->GetFieldID(fpClass, "data", "[B"); /* Starts to fill the obj */ env->SetIntField(obj, height, fpd->height); env->SetIntField(obj, width, fpd->width); env->SetIntField(obj, length, fpd->length); dataArray = env->NewByteArray(FP_PRINT_DATA_DATA_SIZE); env->SetByteArrayRegion(dataArray, 0, FP_PRINT_DATA_DATA_SIZE, (jbyte*)fpd->data); env->SetObjectField(obj, data, dataArray); } 

但是在从JAVA端的JNI代码的这些函数返回后,该方法显示了exception

 java.lang.ArrayIndexOutOfBoundsException at jlibfprint.JlibFprint.binary_image(Native Method) at jlibfprint.SampleRun.main(SampleRun.java:96) 

即对象没有正确处理,并且它不会从JNI层返回任何内容。 但我没有得到我应该在JNI代码中更改的内容,以便它将返回正确的对象。

请建议我任何解决方案。

如果指定的区域超出数组的边界,则GetByteArrayRegion()SetByteArrayRegion()都可以抛出ArrayIndexOutOfBoundsException。

您对SetByteArrayRegion()的调用看起来是正确的 – 它会在创建所需大小的数组之后立即生效。

validationGetByteArrayRegion()访​​问的条目数组的大小是否至少为FP_PRINT_DATA_DATA_SIZE。

顺便说一句,另一种方法是使用GetByteArrayElements()ReleaseByteArrayElements() ,它可以返回指向Java用于Array的相同内存的指针。