Hi,
i just had a nice adventure with GetDirectBufferAddress &
GetPrimitiveArrayCritical. Here's a code snippet
JNIEXPORT jint JNICALL
Java_com_badlogic_gdx_utils_BufferUtils_copyJni___3FLjava_nio_Buffer_2II
(JNIEnv *env, jclass, jfloatArray src, jobject dst, jint numFloats,
jint offset )
{
float* pSrc = (float*)env->GetPrimitiveArrayCritical(src, 0);
float* pDst = (float*)env->GetDirectBufferAddress( dst );
memcpy( pDst, pSrc + (offset << 2), numFloats << 2 );
env->ReleasePrimitiveArrayCritical(src, pSrc, 0);
return (int)pDst;
}
This crashes on the emulator with a sigseg (0xdeadd00d). It works on
all the devices i have (HTC Hero (1.5), Samsung Galaxy S (2.1),
Motorola Droid (2.1) and Nexus 1 (2.2). The code is compiled with the
toolchain from the latest NDK release, no special flags except -O2.
If i swap the first to statements to
float* pSrc = (float*)env->GetPrimitiveArrayCritical(src, 0);
float* pDst = (float*)env->GetDirectBufferAddress( dst );
everything works as expected.
The documenation of GetPrimitiveArrayCritical at
http://download-llnw.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html
says that "Inside a critical region, native code must not call other
JNI functions, or any system call that may cause the current thread to
block and wait for another Java thread." Now i can interpret this in
two ways: no JNI calls what so ever, and additionally no blocking
system calls. Or i could interpret it as no JNI calls that block and
no system calls that block. Give that it works on all the devices as
well as on the latest Sun JRE (yes, it's still Sun in my head...) i
assume the second interpretation should be the correct one.
Should i file a bug or is the sigseg of the first code example in
compliance with the specification?
Ciao,
Mario