Issue
I'm going off of this example of how to pass a com.sun.jna.Structure containing a com.sun.jna.StringArray from Java into native C code using JNA, and having trouble obtaining the Structure contents successfully in the C code.
Note that I can pass a struct from the C code to a Structure in Java successfully, but I'm having trouble creating a Structure in the Java code and successfully sending it to the C code as a struct.
This is the code in question:
String[] user_name_array = new String[3];
user_name_array[0] = "test_user_1";
user_name_array[1] = "test_user_2";
user_name_array[2] = "test_user_3";
StringList.ByReference members = new StringList.ByReference();
members.length = 3;
members.strings = new StringArray(user_name_array);
MyNativeLibrary.myMethod(members);
Seems simple enough, but it's not working.
It gets into the C code successfully as expected, but the Pointer in the Structure is empty, and the length is zero.
Here is the StringList Structure in the Java:
public static class StringList extends Structure {
public volatile long length;
public volatile Pointer strings;
public static class ByValue extends StringList implements Structure.ByValue {}
public static class ByReference extends StringList implements Structure.ByReference {
public ByReference() { }
public ByReference(Pointer p) { super(p); read(); }
}
public StringList() { }
public StringList(Pointer p) { super(p); read(); }
}
Here is the corresponding struct in the C code:
typedef struct string_list {
uint64_t length;
const char **strings;
} string_list;
And here is the method definition in the C code:
const char* my_method(struct string_list *members)
{
//.................
}
Using ndk-gdb, and breaking into this function, this is what it shows:
(gdb) break my_method
(gdb) cont
Continuing.
Breakpoint 1, my_method (members=0x9bee77b0) at ../app/my_code_file.c:368
(gdb) p *members
$1 = {length = 0, strings = 0x0}
It seems like it should work, so why aren't the values making it into the C code? What am I missing?
Also note that I can successfully send a StringArray directly to the C code from the Java code if it's not inside a Structure:
Java:
//This works!
StringList members = MyNativeLib.myTestFunction(3, new StringArray(user_name_array));
C:
//This works!
string_list* my_test_function(uint64_t length, const char **strings)
{
//......
}
It seems that in this case, JNA works as expected. So, why doesn't it work with a Structure as the documentation states it should?
Solution
Don't mark the fields as volatile. When you do that, JNA won't write to them unless you do an explicit Structure.writeField().
Answered By - technomage
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.