Discussion:
Passing data from C via JNI to Java
(too old to reply)
huub
2006-06-06 12:33:44 UTC
Permalink
Hi,

I'm trying to find info on passing data (float array) from C code
through JNI to Java. All I can find though, is either C++/Java or Java
to C. Can somebody give a direction to where I can find C to Java?

Thanks,

Huub
Gordon Beaton
2006-06-06 19:57:26 UTC
Permalink
Post by huub
I'm trying to find info on passing data (float array) from C code
through JNI to Java. All I can find though, is either C++/Java or
Java to C. Can somebody give a direction to where I can find C to
Java?
If you know how to do it in C++ you can do it in C as well. Exactly
what are you having problems with?

To create a float array, declare a jfloatArray and assign it with
NewFloatArray(). To populate it, use (for example)
SetFloatArrayRegion() or GetFloatArrayElements() and
ReleaseFloatArrayElements.

To *return* the float[] from C to Java, declare the native method as
returning float[] and simply return a reference to the array you
created.

To *pass* a float[] from C to a Java method call, use
Call<whatever>Method() and pass the array reference as appropriate.

To *set* a float[] field in a Java object, use SetObjectField().

/gordon
--
[ do not email me copies of your followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
huub
2006-06-07 09:13:10 UTC
Permalink
Thank you for your answer. I tried to do it, but I'm getting these errors:

SonarThread.c:418: error: request for member 'NewFloatArray' in
something not a structure or union
SonarThread.c:419: error: request for member 'SetFloatArrayRegion' in
something not a structure or union

This is the code:

JNIEXPORT jfloatArray
Java_iRescueControl_client_sonar_SonarThread_poll(JNIEnv *env, jclass j)
{
jfloatArray jArray;

open_port();
set_baudrate();
select_object();
close(fd);
jArray = (jfloatArray) env->NewFloatArray(4); (418)
env->SetFloatArrayRegion(jArray, 0, 4, ObjectToJava); (419)
return jArray;
}


Could you explain what may be wrong?

Thank you
Gordon Beaton
2006-06-07 11:14:05 UTC
Permalink
Post by huub
SonarThread.c:418: error: request for member 'NewFloatArray' in
something not a structure or union
SonarThread.c:419: error: request for member 'SetFloatArrayRegion' in
something not a structure or union
[...]
Post by huub
jArray = (jfloatArray) env->NewFloatArray(4); (418)
That's C++. In C, make the JNI calls like this:

(*env)->NewFloatArray(env, 4);

The return type is jfloatArray (not jArray), and the cast is not
necessary.

For more information about the differences in JNI from C and C++:

http://java.sun.com/docs/books/jni/html/other.html#30951
http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/design.html#wp715

/gordon
--
[ do not email me copies of your followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
huub
2006-06-07 13:08:23 UTC
Permalink
Post by Gordon Beaton
Post by huub
jArray = (jfloatArray) env->NewFloatArray(4); (418)
(*env)->NewFloatArray(env, 4);
The return type is jfloatArray (not jArray), and the cast is not
necessary.
You don't mention line 419. Is this line not necessary? On a Sun forum I
found a thread
http://forum.java.sun.com/thread.jspa?threadID=45806&messageID=2309832

telling this:
------
this is for c++::

jfloatArray ret = (jfloatArray)env->NewFloatArray(length of the array);

env->SetFloatArrayRegion(ret,index,number of retunrs,jfloat *);

for c u just have to include the env variable
jfloatArray ret = (jfloatArray)env->NewFloatArray(env,length of the array);

return ret;
------

It sounds like a bit contradicting to your solution. Or do I
misunderstand something?
Post by Gordon Beaton
http://java.sun.com/docs/books/jni/html/other.html#30951
http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/design.html#wp715
Thank you
Gordon Beaton
2006-06-07 14:36:41 UTC
Permalink
Post by huub
You don't mention line 419. Is this line not necessary?
I was just showing how to get past the compilation error, I didn't
think it was necessary to explain that you need to make a nearly
identical change to both lines.
Post by huub
It sounds like a bit contradicting to your solution. Or do I
misunderstand something?
It is the same as my solution. Read the links I posted earlier.

/gordon
--
[ do not email me copies of your followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
Gordon Beaton
2006-06-07 15:43:25 UTC
Permalink
Post by huub
jfloatArray ret = (jfloatArray)env->NewFloatArray(length of the array);
env->SetFloatArrayRegion(ret,index,number of retunrs,jfloat *);
for c u just have to include the env variable
jfloatArray ret = (jfloatArray)env->NewFloatArray(env,length of the array);
It sounds like a bit contradicting to your solution. Or do I
misunderstand something?
Sorry, I said earlier that the above is the same as the solution I had
suggested, but I see now that the above C example is not correct.

In addition to including (or leaving out) the env variable in the JNI
call, you must dereference it differently in C and C++:

C++:
jfloatArray ret = env->NewFloatArray(length);

C:
jfloatArray ret = (*env)->NewFloatArray(env, length);

(and these examples do agree with what I wrote earlier.)

Note that is no need to cast the return type when it already agrees
with the variable on the left hand side of the assignment.

/gordon
--
[ do not email me copies of your followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
huub
2006-06-08 07:51:11 UTC
Permalink
Thank you for helping out.

Continue reading on narkive:
Loading...