Passing Java float array to native function

3,101 views
Skip to first unread message

socratesJ

unread,
Apr 22, 2011, 12:18:06 PM4/22/11
to android-ndk
I'm trying to pass an array of float values to a native C++ function.
Here's what my native function looks like:

float orientation[] = {0.f, 0.f, 0.f};

void
Java_<package>_nativeOrientationChange( JNIEnv* env, jfloatArray
values )
{
float* nativeValues = (float *)env->GetFloatArrayElements(values, 0);

orientation[0] = nativeValues[1];
orientation[1] = nativeValues[2];
orientation[2] = nativeValues[0];

__android_log_print(ANDROID_LOG_INFO, "TEST", "values = %f, %f, %f",
orientation[0], orientation[1], orientation[2]);

env->ReleaseFloatArrayElements(values, nativeValues, 0);
}

That logging call always prints the same three values, regardless of
the values that are passed to this function (0.000000, 34.121906,
0.000000, if it matters).

Any ideas as to what I'm doing wrong?

alan

unread,
Apr 22, 2011, 1:03:34 PM4/22/11
to andro...@googlegroups.com
the result of GetFloatArrayElements may be null and you should be checking it before you use it. your function declaration is missing the parameter for the object/class and should be:
Java_<package>_nativeOrientationChange( JNIEnv*  env, jobject obj, jfloatArray values )

fadden

unread,
Apr 22, 2011, 2:16:20 PM4/22/11
to android-ndk
Or, if it's a static method, nativeOrientationChange( JNIEnv* env,
jclass clazz, ...)

(A jclass is a jobject, so using "jobject obj" is not wrong, but
declaring it as jclass will remind you that it's a class object and
not an instance of something in your app.)

The CheckJNI feature will check the argument to Get/Release and issue
a warning if it's not an array, which would have caught this problem.

socratesJ

unread,
Apr 22, 2011, 2:52:01 PM4/22/11
to android-ndk
This is indeed a static method. Adding the 'jclass clazz' parameter
fixed the issue. I really don't understand why that parameter is
required for a static method, especially since I don't use it
directly. JNI is a bit strange ...

Thanks!

Stephen Williams

unread,
Apr 22, 2011, 6:47:48 PM4/22/11
to andro...@googlegroups.com
There are no globals in Java.  Statics are always relative to an object, a class object.  So the JNI parameters are the same except that it is a specific kind of object for statics.

In my last project, I had some fun adding things to Object in a JDK-based project to do performance monitoring and statistics.  Interesting to see the millions of objects created by Maven etc.

Stephen

fadden

unread,
Apr 25, 2011, 4:25:33 PM4/25/11
to android-ndk
On Apr 22, 11:52 am, socratesJ <mcart...@gmail.com> wrote:
> This is indeed a static method. Adding the 'jclass clazz' parameter
> fixed the issue. I really don't understand why that parameter is
> required for a static method, especially since I don't use it
> directly. JNI is a bit strange ...

You declared it:

nativeOrientationChange(JNIEnv*, jfloatArray)

for a static method it should be be:

nativeOrientationChange(JNIEnv*, jclass, jfloatArray)

for a virtual method it should be:

nativeOrientationChange(JNIEnv*, jobject, jfloatArray)

Note 3 args instead of 2. You were making float array calls on the
class object. With CheckJNI enabled these situations are detected,
without it the VM skips the extra overhead of type checking and just
does what you ask.
Reply all
Reply to author
Forward
0 new messages