This week's book giveaway is in the Kotlin forum.
We're giving away four copies of Kotlin in Action and have Dmitry Jemerov & Svetlana Isakova on-line!
See this thread for details.
Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

JNI: Understanding how to access a String array  RSS feed

 
Keith L
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Within a native program, I wanted to be able to read from and write to a String array declared within my Java program. I took this example from the JNI tutorial as my starting point, modifying it to use a String array instead of a String. I initially expected to be able to modify the elements of the String array directly by using SetObjectArrayElement(). However, I couldn't get that to work so I decided to try copying the java Sring array into a native jobjectArray, intending to modify it in the native program and then pass it back with SetObjectField().

What surprised me, was that I didn't need to write the jobjectArray back. Modifying the jobjectArray in the native program, modified the String array in the java program. So it seems that, whereas I thought I was creating a local object in the native program, I was actually creating a pointer to hold a reference to the java object. It's all good because that's what I wanted to do. But as I don't completely understand C's use of pointers and inderection I still have one or two doubts.

Anyway, my question is: have I understood correctly what is happening. Does "jobjarray = (*env)->GetObjectField(env, obj, fid);" actually set up a pointer to the s instance variable? And is this the best way to code this? Can I do it without creating a jobjectArray at all?

Thanks
Keith


This is an outline of the code.

Java
----


Native Program
--------------

Java
----

/* S now contains "Ah", "kh", "xyz", "jh", "th" */
 
Jayesh Lalwani
Ranch Hand
Posts: 502
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, I beleive your analysis is correct. Any java object accessed from C++ is actually a pointer to the actual java object. That's why if you call any Java methods on the jobject using C++, the actual Java object gets invoked.

Since, in Java, an array itself is an object, the same rules apply. Any calls made to the jobjectArray will reflect on the actual array in Java.

I don't know why you would want to do it any other way, except you might want to (if you haven't already) check the length of the array before you set the element.

OR if you want to be more safe, you might want to prevent exposing the array. So, instead of this



You might want to do this



Then in your C++ code, you call setS instead of accessing the string directly. This gives you an opportunity to do some validations in Java code instead of C++ code, and also reduces the amount of C++ code.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!