Java JNI SetFloatArrayElement()不工作

Java JNI SetFloatArrayElement()不工作,java,android,c++,android-ndk,Java,Android,C++,Android Ndk,我试图在将jfloatArray返回到JavaAndroid代码之前修改其中的一些值。 我发现我不能使用常规方法newArray[I]=result[I]来做,我应该做env->SetFloatArrayElement(newArray,I,result[I]) 问题是此函数会引发以下错误: [armeabi-v7a]编译++arm:tensorflow_mnist SetFloatArrayElement(newArray,i,result[i]); ^ 代码: JNIEXPORT jfloa

我试图在将jfloatArray返回到JavaAndroid代码之前修改其中的一些值。 我发现我不能使用常规方法
newArray[I]=result[I]
来做,我应该做
env->SetFloatArrayElement(newArray,I,result[I])

问题是此函数会引发以下错误:

[armeabi-v7a]编译++arm:tensorflow_mnist SetFloatArrayElement(newArray,i,result[i]); ^

代码:

JNIEXPORT jfloatArray JNICALL
TENSORFLOW_方法(detectDigit)(JNIEnv*env、jobject thiz、金泰原始像素){
jboolean iCopied=JNI_FALSE;
jint*pixels=env->GetIntArrayElements(原始像素和图标);
jfloatArray newArray=env->NewFloatArray(2);
jfloat*结果=过程(重新解释投影(像素));
对于(int i=0;i
我试图在将jfloatArray返回到java Android代码之前修改它中的一些值。我发现我不能使用常规方法
newArray[I]=result[I];
来执行此操作,而应该执行
env->SetFloatArrayElement(newArray,I,result[I]);

你怎么会这么想?正如编译器告诉你的,JNI没有
SetFloatArrayElement()
函数。只有
Object
数组有一个元素设置函数,即
SetObjectArrayElement()

处理基元数组有几种选择

  • 经典的机制是使用适当的
    Get*ArrayElements()
    函数来获取普通数组,修改数组,然后
    releaseArayelements()
    。另外请注意,使用这种方法,如果您想要提交更改(就像您所做的那样)然后必须使用模式
    0
    JNI\u提交
    ,而不是
    JNI\u中止

  • <> LI>

    对于不调用其他JNI函数的快速运行用途,可以考虑<代码> GETPrimiVielayRayPrimalAd()/<代码>和<代码> RelasePrimiViaRayEnrimalAd()/Cuff>。但是,如果在GET和Office之间执行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;
}
JNIEXPORT jfloatArray JNICALL
TENSORFLOW_方法(detectDigit)(JNIEnv*env、jobject thiz、金泰原始像素){
jfloatArray newArray=env->NewFloatArray(2);
jint*pixels=env->GetIntArrayElements(原始像素,空);
jfloat*结果=过程(重新解释投影(像素));
环境->发布阵列元素(原始像素、像素、JNI\u中止);
env->SetFloatArrayRegion(新数组,0,2,结果);
自由(结果);
返回新数组;
}

如果您可以依赖<代码>进程()/Cuff>函数运行得很快,并且没有任何阻塞的可能性,那么您可以考虑使用<代码> GETPrimiVielayRayPrimalAL()/<代码>和<代码> RelasePrimiViaRayPrimeAc临界()

访问像素阵列。由于避免制作像素阵列的副本,这可能会更有效,但决不能确定您正在使用的方法是否会制作副本。(请特别注意,
GetIntArrayElements()的第二个参数)
是一个输出变量;它报告是否已复制,但不指示是否已复制)

我试图在将jfloatArray返回到java Android代码之前修改它中的一些值。我发现我不能使用常规方法
newArray[I]=result[I];
来执行此操作,而应该执行
env->SetFloatArrayElement(newArray,I,result[I]);

你怎么会这么想?正如编译器告诉你的,JNI没有
SetFloatArrayElement()
函数。只有
Object
数组有一个元素设置函数,即
SetObjectArrayElement()

处理基元数组有几种选择

  • 经典的机制是使用适当的
    Get*ArrayElements()
    函数来获取普通数组,修改数组,然后
    releaseArayelements()
    。另外请注意,使用这种方法,如果您想要提交更改(就像您所做的那样)然后必须使用模式
    0
    JNI\u提交
    ,而不是
    JNI\u中止

  • <> LI>

    对于不调用其他JNI函数的快速运行用途,可以考虑<代码> GETPrimiVielayRayPrimalAd()/<代码>和<代码> RelasePrimiViaRayEnrimalAd()/Cuff>。但是,如果在GET和Office之间执行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;
}
JNIEXPORT jfloatArray JNICALL
TENSORFLOW_方法(detectDigit)(JNIEnv*env、jobject thiz、金泰原始像素){
jfloatArray newArray=env->NewFloatArray(2);
jint*pixels=env->GetIntArrayElements(原始像素,空);
jfloat*结果=过程(重新解释投影(像素));
环境->发布阵列元素(原始像素、像素、JNI\u中止);
env->SetFloatArrayRegion(新数组,0,2,结果);
自由(结果);
返回新数组;
}

如果您可以依赖<代码>进程()/Cuff>函数运行得很快,并且没有任何阻塞的可能性,那么您可以考虑使用<代码> GETPrimiVielayRayPrimalAL()/<代码>和<代码> RelasePrimiViaRayPrimeAc临界()

访问像素阵列。由于避免制作像素阵列的副本,这可能会更有效,但是