gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:08:07 24 4
gpt4 key购买 nike

我有一个 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<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 代码的这些函数返回后,该方法显示异常

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

即对象没有被正确处理并且它没有从 JNI 层返回任何东西。但是我没有得到我应该在 JNI 代码中更改什么,以便它返回正确的对象。

请给我任何解决方案。

最佳答案

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

您对 SetByteArrayRegion() 的调用看起来是正确的——它紧接着创建了所需大小的数组。

验证入口数组的大小,由 GetByteArrayRegion() 访问,至少为 FP_PRINT_DATA_DATA_SIZE。

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

关于java - 如何使用 JNI 传递和接收对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18381076/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com