如何使用JNI传递和接收对象 [英] How to pass and receive objects using JNI
问题描述
我有一个 JAVA
应用程序,因为我想将对象作为参数传递给 C
代码使用 JNI
再次,我想从 C
代码中的对象收到 JAVA
使用 JNI
。
I have an JAVA
application in that I want to pass the object as a parameter to the C
code using JNI
and again I want to receive the object from the C
code to JAVA
using JNI
.
在JAVA方面,我只是创建一个应用程序并将其传递给该方法如下所示
In JAVA side i have simply created an application and pass it to the method as shown bellow
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代码如下所示:
And JNI code for the method is as shown bellow :
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<jbyteArray>(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代码的这些函数返回后,该方法显示例外如
But after returning from these functions of JNI code at the JAVA side the method shows the exception like
java.lang.ArrayIndexOutOfBoundsException
at jlibfprint.JlibFprint.binary_image(Native Method)
at jlibfprint.SampleRun.main(SampleRun.java:96)
即对象不正确处理,不会从JNI层返回任何东西。
但是我没有得到JNI代码中应该改变的内容,以便它返回正确的对象。
i.e objects are not process correctly and it does not return any thing from the JNI layer. But I am not getting what should I change in the JNI code so that it will return the correct object.
请给我建议任何解决方案。 >
Please suggest me any solution.
推荐答案
GetByteArrayRegion()
和 SetByteArrayRegion() / code>可以抛出ArrayIndexOutOfBoundsException,如果指定的区域超出数组边界。
Both GetByteArrayRegion()
and SetByteArrayRegion()
can throw ArrayIndexOutOfBoundsException if the specified region goes outside the bounds of the array.
您对SetByteArrayRegion()的调用看起来是正确的 - 立即创建所需大小的数组。
Your call to SetByteArrayRegion() looks correct -- it immediately follows creation of the array of the required size.
验证由GetByteArrayRegion()访问的条目数组的大小至少为FP_PRINT_DATA_DATA_SIZE。
Verify that the size of the array on entry, accessed by GetByteArrayRegion(), is at least FP_PRINT_DATA_DATA_SIZE.
顺便说一下,另一种方法是使用 GetByteArrayElements()
和 ReleaseByteArrayElements()
,其中可能返回指向Java使用的相同内存的指针数组。
By the way, an alternative is to use GetByteArrayElements()
and ReleaseByteArrayElements()
, which may return a pointer to the same memory Java uses for the Array.
这篇关于如何使用JNI传递和接收对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!