0

我想在浮点数[100000]之外的任何地方传递一个大的浮点数数组。我有一个设置成功地传递了一个大小为 212 的数组。但是任何更大的它都会崩溃,并在 logcat 中给出以下错误消息:

“致命信号 11 (SIGSEGV) 位于 0xbe949000 (code=1)”

我的代码

本机功能

NIEXPORT jfloatArray JNICALL  Java_carron_graphics_benchmark_NativeWrapper_getArrayNative(JNIEnv * env, jclass cls) {

    int tempSize = mParticleSystem->mSizeOfSystem*2;

    jfloat cArray[tempSize];
    jsize len = sizeof(cArray);

    jfloatArray jArray = (*env).NewFloatArray(len);

    if (jArray != NULL) {

        jint i;

        for (i = 0; i < tempSize; i++) {
            cArray[i] = mParticleSystem->mParticlePositions[i];
        }
        (*env).SetFloatArrayRegion(jArray, 0, len, cArray);
    }
    return jArray;
}

Java 非常简单,只需抓取数组即可。如果我创建并传递一个大于 212 的浮点数组,尽管我得到了如上所示的错误。

float tempArray[] = NativeWrapper.getArrayNative();

有没有人遇到过这个问题或者可以看到我如何绕过这个限制?如果这个问题已经得到回答,我也很抱歉,我找不到这个具体的问题也没有答案。任何帮助将不胜感激 :)

编辑:

用于在通过 jni 频繁获取数组时更新全局 jfloatArray 以避免垃圾收集器。

static jfloatArray gArray = NULL;

JNIEXPORT jfloatArray JNICALL Java_carron_graphics_benchmark_NativeWrapper_getArrayNative(JNIEnv * env, jclass cls)  {
    int arrayLength = mParticleSystem->mSizeOfSystem*2;

    if (gArray == NULL)
    {
        // create array
        jfloatArray jArray;
        jArray = env->NewFloatArray(arrayLength);
        gArray = (jfloatArray)env->NewGlobalRef(jArray);
    }

    // Update global 
    env->SetFloatArrayRegion(gArray, 0, arrayLength, mParticleSystem->mParticlePositions);

    return gArray;
}
4

2 回答 2

2

您的代码的问题是堆栈的大小有限。你不能把大数组(jfloat cArray[tempSize]变量)放在那里。如果您想创建大型数组,请在堆上执行此操作,就像 Alex 向您展示的那样。

如果mParticleSystem->mParticlePositions是浮点数组,那么这段代码会更好:

int tempSize = mParticleSystem->mSizeOfSystem*2;
jfloatArray jArray = env->NewFloatArray(tempSize);

if (jArray != NULL)
{
    env->SetFloatArrayRegion(jArray, 0, tempSize, mParticleSystem->mParticlePositions);
}
return jArray;

如果它不是浮点数组,则使用以下代码,无需创建额外的浮点数组:

int tempSize = mParticleSystem->mSizeOfSystem*2;
jfloatArray jArray = env->NewFloatArray(tempSize);

if (jArray != NULL)
{
    if (float* ptr = env->GetFloatArrayElements(jArray, NULL))
    {
        for (int i=0; i<tempSize; i++)
        {
            ptr[i] = mParticleSystem->mParticlePositions[i];
        }
        env->ReleaseFloatArrayElements(jArray, ptr, JNI_COMMIT);
    }
}

return jArray;

编辑

要将 jArray 存储在其他地方(例如全局),请执行以下操作:

static jfloatArray gArray = NULL;

jfloatArray fun(...)
{
    jfloatArray jArray;

    if (gArray == NULL)
    {
        // create array
        jArray = env->NewFloatArray(tempSize);
        gArray = (jfloatArray)env->NewGlobalRef(jArray);
    }
    else
    {
        jArray = gArray;
    }

    // ... here fill/modify jArray
    // SetFLoatArrayRegion/GetFloatArrayElemeents/ReleaseFloatArrayElements

    return jArray;
}

完成后释放内存:

void freeArray(...)
{
    env->DeleteGlobalRef(gArray);
    gArray = NULL;
}
于 2013-01-02T06:52:05.100 回答
0

您的代码无法编译:您可能有

jfloat *cArray = new jfloat[tempSize];

在您编译的代码中。

您的代码中的错误是调用 NewFloatArray()。您应该调用 NewFloatArray(tempSize),而不是 (sizeof(cArray))。

另请注意,无需使用 mParticleSystem->mParticlePositions 的中间副本。如果它是一个浮点数组,您可以简单地将它用于 SetFloatArrayRegion()。

于 2013-01-02T06:30:15.853 回答