JNI SetFloatArrayElement() not working

JNI SetFloatArrayElement() not working

本文关键字:not working SetFloatArrayElement JNI      更新时间:2023-10-16

我试图在jfloatArray返回到java Android代码之前修改一些值。我发现我不能用常规的方法newArray[i] = result[i];来做这件事,而应该用env->SetFloatArrayElement(newArray,i,result[i]);

问题是这个函数抛出错误:

[armeabi-v7a] Compile++ arm: tensorflow_mnist <= tensorflow_jni.ccjni/。/tensorflow_jni。cc:在函数'_jfloatArray*中Java_jp_narr_tensorflowmnist_DigitDetector_detectDigit (JNIEnv *,jobject, jintArray)': jni/./tensorflow_jni。抄送:171:14:错误:'JNIEnv'没有名为"SetFloatArrayElement"的成员env -> SetFloatArrayElement (newArray,我,结果[我]);^

代码:

JNIEXPORT jfloatArray JNICALL
TENSORFLOW_METHOD(detectDigit)(JNIEnv* env, jobject thiz, jintArray raw_pixels) {
    jboolean iCopied = JNI_FALSE;
    jint* pixels = env->GetIntArrayElements(raw_pixels, &iCopied);
    jfloatArray newArray = env->NewFloatArray(2);
    jfloat *result = process( reinterpret_cast<int*>(pixels) );

    for(int i=0; i<2; ++i) {
        //VLOG(0) <<  " (" << i << "): " << newArray[i];
        //newArray[i] = result[i];
        //env->SetFloatArrayElement(newArray,i,result[i]);
     }

    env->ReleaseIntArrayElements(raw_pixels, pixels, JNI_ABORT);
    env->ReleaseFloatArrayElements(newArray, result, JNI_ABORT);
    free(result);
    return newArray;
}

我试图修改一些值在jfloatArray返回到java Android代码之前。我发现我不能用常规的方法newArray[i] = result[i];来做这件事,我应该用env->SetFloatArrayElement(newArray,i,result[i]);

你为什么那么想?编译器告诉您,JNI没有SetFloatArrayElement()函数。单元素设置函数仅适用于Object数组,即SetObjectArrayElement()

有几种处理原始数组的方法。

  • 经典的机制是使用适当的Get*ArrayElements()函数获得一个普通的数组,修改数组,然后ReleaseArrayElements()。还请注意,使用这种方法,如果您想提交更改,那么您必须使用模式0JNI_COMMIT,而不是JNI_ABORT

  • 对于不调用其他JNI函数的快速使用,您可以考虑GetPrimitiveArrayCritical()ReleasePrimitiveArrayCritical()。但是,如果在get和release之间进行任何I/O操作,则不应该这样做。

  • 但是,对于您的具体情况,我建议使用SetFloatArrayRegion()。有一个相应的GetFloatArrayRegion(),但你不需要它,因为你不关心固定或关于(Java)数组元素的初始值。

使用第三个选项可能看起来像这样:

JNIEXPORT jfloatArray JNICALL
TENSORFLOW_METHOD(detectDigit)(JNIEnv* env, jobject thiz, jintArray raw_pixels) {
    jfloatArray newArray = env->NewFloatArray(2);
    jint* pixels = env->GetIntArrayElements(raw_pixels, NULL);
    jfloat *result = process( reinterpret_cast<int*>(pixels) );
    env->ReleaseIntArrayElements(raw_pixels, pixels, JNI_ABORT);
    env->SetFloatArrayRegion(newArray, 0, 2, result);
    free(result);
    return newArray;
}

如果你可以依靠process()函数运行非常快,没有任何阻塞的可能性,那么你可以考虑使用GetPrimitiveArrayCritical()ReleasePrimitiveArrayCritical()来访问像素数组。由于避免复制像素数组,这可能会更有效,但绝不能肯定您已经使用的方法会进行复制。(特别注意,GetIntArrayElements()的第二个参数是一个输出变量;它报告是否复制,但不指示)。