I am wanting to pass a single large array of floats anywhere up too and beyond float[100000]. I have a setup successfully passing an array of size 212. But any larger and it crashes giving the following error message in the logcat:
"Fatal signal 11 (SIGSEGV) at 0xbe949000 (code=1)"
Native function
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 Pretty straight forward simply grabbing the array. If I create and pass a float array larger than 212 though I get the error as shown above.
float tempArray[] = NativeWrapper.getArrayNative();
Has anyone encountered this problem or can see how I can get around this limit? Also I apologise if this question has been answered already, I could not find this specific issue nor an answer. Any help will be appreciated :)
EDIT:
For updating a global jfloatArray to avoid the garbage collector when frequently fetching an array through 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;
}
Problem with your code is that stack is limited in size. You can not put there large arrays ( jfloat cArray[tempSize]
variable). If you want to create large array, do that on heap, like Alex is showing you.
If mParticleSystem->mParticlePositions
is float array then this code will be better:
int tempSize = mParticleSystem->mSizeOfSystem*2;
jfloatArray jArray = env->NewFloatArray(tempSize);
if (jArray != NULL)
{
env->SetFloatArrayRegion(jArray, 0, tempSize, mParticleSystem->mParticlePositions);
}
return jArray;
If it is not float array then use following code, no need to create additional float array:
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;
EDIT
To store jArray somewhere else (for example globally) do following:
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;
}
When done free the memory:
void freeArray(...)
{
env->DeleteGlobalRef(gArray);
gArray = NULL;
}
Your code does not compile: you probably had
jfloat *cArray = new jfloat[tempSize];
in your compiled code.
The mistake in your code is in call to NewFloatArray(). You should call NewFloatArray(tempSize), not (sizeof(cArray)).
Also note that there is no need to work with intermediate copy of mParticleSystem->mParticlePositions. If it is an array of float, you can simply use it for SetFloatArrayRegion().
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.