【问题标题】:JNA receive array of structures from CJNA 从 C 接收结构数组
【发布时间】:2014-06-11 15:59:42
【问题描述】:

我有 C 代码,我正在尝试使用 JNA 将其包装到 Java 中的函数调用中。在这段代码中,我声明了以下结构,其中 struct B 是 aFunction(我在 Java 库中包装的函数)的返回值。

CORE_EXPORT typedef struct{
   int number;
   char* word;
} A;

CORE_EXPORT typedef struct{
   int numElements;
   A** Astructures;
} B;

CORE_EXPORT B* aFunction(int num);

以下是我对该函数的 Java 包装器:

public class MyLibrary extends Library{

    B aFunction(int num);

    public static class A extends Structure implements Structure.ByReference {
       public int number;
       public String word;

       public A(Pointer p){
            super(p);
            read();
        }

        @Override
        protected List getFieldOrder() {
             return Arrays.asList("number","word");
        }
     }

   public static class B extends Structure implements Structure.ByValue {
       public PointerByReference Astructures;
       public int numElements;

       public B(Pointer p){
            super(p);
            read();
        }

        @Override
        protected List getFieldOrder() {
             return Arrays.asList("numElements","Astructures");
        }
     }
}

根据我对 JNA 的理解,我尝试通过以下方式将 aFunction 返回的结构中的 PointerByReference 取消引用到 A 结构的数组:

MyLibrary.B structB = aFunction(1);
PointerByReference ptrRef = structB.Astructures;
Pointer[] pointersToStructs = ptrRef.getValue().getPointerArray(0);

//use each of these pointers to create each A struct
MyLibrary.A[] aStructures = new MyLibrary.A[pointersToStructs.length];
for(int i = 0; i < pointersToStructs.length; i++){
    aStructures[i] = new MyLibrary.A(pointersToStructs[i]);
}

调用该函数可以正常工作,但是当我尝试从 aFunction 返回的结构 B 中提取 A 结构数组时,我收到一条错误消息,指出“A 返回的名称 ([number,word]) 与声明的字段名称 ([])"。当我在 Java 中取消引用 PointerByReference 时,我做错了什么吗?

谢谢!

更新:

经过更多研究,我将解压结构数组的方法更改为:

MyLibrary.B structB = aFunction(1);
Pointer resultPtr = structB.Astructures.getValue();
MyLibrary.A tempStruct = new MyLibrary.A(resultPtr);
tempStruct.read();
MyLibrary.A[] aStructures = (MyLibrary.A[])tempStruct.toArray(structB.numElements);

当执行第二行 (structB.Astructures.getValue()) 时,我现在收到 Java 运行时环境 (SIGSEGV) 检测到的致命错误。这说明有问题的框架是C [libc.so.6+0x89a00] memcpy+0xa0。

【问题讨论】:

    标签: jna


    【解决方案1】:

    number 和 word 必须是公共字段。错误信息表示 JNA 找不到与您在getFieldOrder() 中声明的名称对应的适当字段;如果您希望Structure 的字段映射到等效的本地字段,则它们必须是公共成员。

    更新

    您的getFieldOrder()(在任一类中)都无法编译。

    此外,您的本机函数aFunction 返回一个struct*,这意味着它绝对应该不使用Structure.ByValue 作为返回类型。

    你应该返回一个Pointer(如果你需要释放内存)或者只是一个从Structure派生的返回类型(Structure.ByReference是隐含的返回类型)。

    如果您不熟悉指针和结构解引用,通常在使用 JNA 时应该使用 Pointer 类型。获得功能映射后,您可以稍后让事情变得更简单、更自动化。

    请参阅FAQ,了解应如何映射各种指针和数组变体。

    【讨论】:

    • 对不起,我错过了在写问题时,数字和单词在 Struct 类中被声明为公共字段,但我仍然收到此错误。我已经用这个修改更新了问题,谢谢!
    • 这很奇怪,它们对我来说编译得很好。但是好的,谢谢,我会尝试使用指针来使映射工作。
    • 我的错误,我不知道Arrays.asList(T... a) 的“较新”声明。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多