0

float [100000]を超えて、floatの単一の大きな配列をどこにでも渡したいと思っています。サイズ212の配列を正常に渡すセットアップがあります。しかし、それより大きくするとクラッシュし、logcatに次のエラーメッセージが表示されます。

「0xbe949000(コード= 1)での致命的な信号11(SIGSEGV)」

私のコード

ネイティブ機能

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配列を作成して渡すと、

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が示しているように、ヒープ上で作成します。

がfloat配列の場合mParticleSystem->mParticlePositions、このコードの方が適しています。

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

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

float配列でない場合は、次のコードを使用します。追加のfloat配列を作成する必要はありません。

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()の呼び出しにあります。(sizeof(cArray))ではなく、NewFloatArray(tempSize)を呼び出す必要があります。

また、mParticleSystem->mParticlePositionsの中間コピーを操作する必要がないことにも注意してください。floatの配列の場合は、SetFloatArrayRegion()に使用できます。

于 2013-01-02T06:30:15.853 に答える