【问题标题】:How to pass a com.sun.jna.Structure from Java to struct in C, using JNA如何使用 JNA 将 com.sun.jna.Structure 从 Java 传递到 C 中的结构
【发布时间】:2016-08-06 18:42:36
【问题描述】:

我将离开 this 示例,说明如何使用 JNA 将包含 com.sun.jna.StringArraycom.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代码,但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
$1 = {length = 0, strings = 0x0}

看起来它应该可以工作,那么为什么没有将它的值放入 C 代码中呢?我错过了什么?

另外请注意,如果 StringArray 不在结构中,我可以成功地将 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

【问题讨论】:

  • @DougStevenson 看起来这是如何传递 StringArray 的解决方案,而不是如何传递包含 StringArray 的结构,所以不是一个好的欺骗目标....
  • 您不会自动将 java 结构映射到 C 结构。您必须使用 JNI 以编程方式将感兴趣的成员从传递的 jobject 对象中提取出来,而字符串数组是处理起来最费力的事情。这有点痛苦。
  • 也许这更有帮助。 stackoverflow.com/questions/3923299/…
  • 不要将字段标记为volatile。当你这样做时,JNA 不会写信给他们,除非你明确地写了Structure.writeField()

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


【解决方案1】:

不要将字段标记为易失性。当您这样做时,除非您执行明确的 Structure.writeField(),否则 JNA 不会写信给他们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 2023-03-17
    相关资源
    最近更新 更多