如何使用JNA将com.sun.jna.Structure从Java传递到C中的struct

时间:2016-04-15 00:12:32

标签: java android android-ndk java-native-interface jna

我离开symbolab示例,了解如何使用JNA将包含thiscom.sun.jna.Structure从Java传递到本机C代码,并且无法获取结构内容成功地在C代码中。

请注意,我可以成功地将结构从C代码传递给Java中的结构,但是我在Java代码中创建结构并成功将其作为结构发送到C代码时遇到了问题。

这是有问题的代码:

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);

看起来很简单,但它无法正常工作。

它按预期成功进入C代码,但结构中的指针为空,长度为零。

这是Java中的StringList结构:

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(); }
}

这是C代码中的相应结构:

typedef struct string_list {
    uint64_t length;
    const char **strings;
} string_list;

以下是C代码中的方法定义:

const char* my_method(struct string_list *members)
{
   //.................
}

使用ndk-gdb,并打破此功能,这是它显示的内容:

(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}

它似乎应该可以工作,那么为什么这些值不能成为C代码呢?我错过了什么?

另请注意,如果它不在结构中,我可以成功地将StringArray从Java代码直接发送到C代码:

爪哇:

//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)
{
    //......
}

在这种情况下,似乎JNA按预期工作。那么,为什么它不适用于结构com.sun.jna.StringArray

1 个答案:

答案 0 :(得分:3)

不要将字段标记为易变。当你这样做时,除非你做一个显式的Structure.writeField(),否则JNA不会写信给他们。