如何使用 JNA 将 com.sun.jna.Structure 从 Java 传递到 C 中的结构
How to pass a com.sun.jna.Structure from Java to struct in C, using JNA
我要使用 JNA 从 this example of how to pass a com.sun.jna.Structure containing a com.sun.jna.StringArray 从 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代码,但Structure中的Pointer为空,长度为零
这里是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
= {length = 0, strings = 0x0}
看起来它应该可以工作,那么为什么这些值没有进入 C 代码?我错过了什么?
另请注意,如果不在结构中,我可以从 Java 代码成功地将 StringArray 直接发送到 C 代码:
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)
{
//......
}
看来在这种情况下,JNA 可以正常工作。那么,为什么它不适用于结构 as the documentation states it should?
不要将字段标记为可变的。当您这样做时,JNA 不会写信给他们,除非您明确地执行 Structure.writeField().
我要使用 JNA 从 this example of how to pass a com.sun.jna.Structure containing a com.sun.jna.StringArray 从 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代码,但Structure中的Pointer为空,长度为零
这里是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
= {length = 0, strings = 0x0}
看起来它应该可以工作,那么为什么这些值没有进入 C 代码?我错过了什么?
另请注意,如果不在结构中,我可以从 Java 代码成功地将 StringArray 直接发送到 C 代码:
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)
{
//......
}
看来在这种情况下,JNA 可以正常工作。那么,为什么它不适用于结构 as the documentation states it should?
不要将字段标记为可变的。当您这样做时,JNA 不会写信给他们,除非您明确地执行 Structure.writeField().