【发布时间】:2022-06-10 21:52:56
【问题描述】:
我正在做一个项目,需要在 C++ 中使用 3D 数组进行一些计算。我需要将这个 3D 数组从 Java 传递到 C++,进行一些计算,然后返回它。我正在使用 JNI 并且对它很陌生,所以我不太了解。我正在尝试制作一个示例程序来测试它并将其用作参考。我已经将 2D 数组传递给 C++,但无法弄清楚 3D 部分。我使用 this solution 构建了 2D 部分。
这是我现在的 C++ 代码(适用于二维数组):
float*** testFunction(float ***a)
{
printf("Hello from JNI!\n");
printf("Point at %d,%d,%d is: %f\n", 1, 2, 2, a[1][2]);
return a[1][2][2];
}
jfloat JNICALL Java_JNIArray_integrateWithTrapezoid(JNIEnv *env, jobject thisObj, jobjectArray jarr)
{
int sizex = env->GetArrayLength(jarr);
jfloatArray dim = (jfloatArray)env->GetObjectArrayElement(jarr, 0);
int sizey = env->GetArrayLength(dim);
float **localArray;
localArray = new float *[sizex];
for (int i = 0; i < sizex; i++)
{
jfloatArray oneDim = (jfloatArray)env->GetObjectArrayElement(jarr, i);
jfloat *element = env->GetFloatArrayElements(oneDim, 0);
localArray[i] = new float[sizey];
for (int j = 0; j < sizey; j++)
{
localArray[i][j] = element[j];
}
}
return trapezoidalintegral(localArray);
}
任何帮助都会很棒。我对此一无所知。如果我忘记提供任何需要的信息,请告诉我。
谢谢。
编辑:
感谢@Botje,这成功了:
void trapezoidalintegral(float ***a)
{
printf("Hello from JNI!\n");
printf("Point at %d, %d, %d is: %f\n", 1, 2, 2, a[1][2][2]);
return;
}
float *thirdLevel(JNIEnv *env, jfloatArray arr)
{
jsize len = env->GetArrayLength(arr);
float *ret = new float[len];
env->GetFloatArrayRegion(arr, 0, len, ret);
return ret;
}
float **secondLevel(JNIEnv *env, jobjectArray arr)
{
jsize len = env->GetArrayLength(arr);
float **ret = new float *[len];
for (int i = 0; i < len; i++)
{
jobject item = env->GetObjectArrayElement(arr, i);
ret[i] = thirdLevel(env, (jfloatArray)item);
env->DeleteLocalRef(item);
}
return ret;
}
float ***firstLevel(JNIEnv *env, jobjectArray arr)
{
jsize len = env->GetArrayLength(arr);
float ***ret = new float **[len];
for (int i = 0; i < len; i++)
{
jobject item = env->GetObjectArrayElement(arr, i);
ret[i] = secondLevel(env, (jobjectArray)item);
env->DeleteLocalRef(item);
}
return ret;
}
JNIEXPORT jobjectArray JNICALL Java_JNIArray_integrateWithTrapezoid(JNIEnv *env, jobject thisObj, jobjectArray jarr)
{
float ***returningArray;
returningArray = firstLevel(env, jarr);
trapezoidalintegral(returningArray);
jclass *pClass;
jclass cls1;
jclass jcls1;
jclass jcls2;
jobject obj2;
cls1 = env->GetObjectClass(thisObj);
// jfieldID fid1 = env->GetFieldID(cls1, "ptr", "J");
// pClass = (jclass *)env->GetLongField(thisObj, fid1);
jcls1 = env->FindClass("[[F");
jcls2 = env->FindClass("[F");
jobjectArray array1 = env->NewObjectArray(3, jcls1, NULL);
for (int i = 0; i < 3; i++)
{
jobjectArray array2 = env->NewObjectArray(3, jcls2, NULL);
for (int j = 0; j < 3; j++)
{
jfloatArray array3 = env->NewFloatArray(3);
env->SetFloatArrayRegion(array3, 0, 3, returningArray[i][j]);
env->SetObjectArrayElement(array2, j, array3);
}
env->SetObjectArrayElement(array1, i, array2);
}
env->DeleteLocalRef(cls1);
env->DeleteLocalRef(jcls1);
env->DeleteLocalRef(jcls2);
return array1;
}
【问题讨论】:
-
锯齿状 3D 数组与锯齿状 2D 数组相同,中间填充了额外的指针数组。
float **localArray = new float **[sizex];,然后是一个将new float *[sizey];放入localarray的循环,然后是另一个将new float[sizez]s 放入每个float*数组的循环。像一样丑陋,不是吗?而是考虑一个庞大的 1D 数组并使用索引数学来假装它是 3D。 -
@user4581301 我不会像
float ***localArray = new float**[sizex];那样初始化数组吗? -
是的。对于那个很抱歉。当我剪切、粘贴和更新时错过了开始..
标签: java c++ java-native-interface