[英]Android passing large float arrays from native to java via jni. Getting error if over certain size
我想在整个float和[100000]之外的任何地方传递一个大型的float数组。 我有一个安装程序成功传递了大小为212的数组。但是任何较大的安装程序都会崩溃,并在logcat中给出以下错误消息:
“致命信号11(SIGSEGV)位于0xbe949000(代码= 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数组,尽管出现了如上所述的错误。
float tempArray[] = NativeWrapper.getArrayNative();
有没有人遇到这个问题,或者可以看到我如何解决这个限制? 我也很抱歉,如果这个问题已经得到回答,我找不到这个特定问题或答案。 任何帮助将不胜感激 :)
编辑:
用于更新全局jfloatArray以避免在频繁通过jni提取数组时避免垃圾回收器。
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;
}
您的代码的问题是堆栈的大小受到限制。 您不能在其中放置大型数组( 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;
如果不是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;
}
您的代码无法编译:您可能有
jfloat *cArray = new jfloat[tempSize];
在您的编译代码中。
您的代码中的错误是在调用NewFloatArray()。 您应该调用NewFloatArray(tempSize),而不是(sizeof(cArray))。
另请注意,无需使用mParticleSystem-> mParticlePositions的中间副本。 如果它是一个float数组,则可以将其简单地用于SetFloatArrayRegion()。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.