JNA从C接收结构数组

时间:2014-06-11 15:59:43

标签: jna

我有C代码,我试图使用JNA将其包装到Java中的函数调用中。在这段代码中,我声明了以下结构,其中struct B是aFunction的返回值(函数I' m包装在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返回的struct B中提取A结构数组时,我收到一条错误,指出&#34; A返回名称([number,word])与声明的字段名称([])&#34;不匹配。当我在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。

1 个答案:

答案 0 :(得分:0)

numberword必须是公共字段。该错误消息表明JNA找不到与您在getFieldOrder()中声明的名称相对应的相应字段; Structure的字段必须是公共成员,如果您希望它们映射到等效的本地字段。

<强>更新

你的getFieldOrder()(在任一课程中)都不会编译。

此外,您的原生函数aFunction会返回struct*,这意味着它绝对应该使用Structure.ByValue作为返回类型。

你应该返回一个Pointer(如果你需要处理内存)或只是一个从Structure派生的返回类型(Structure.ByReference暗示了返回类型)。

通常在使用JNA时,如果您不熟悉指针和结构解除引用,则应使用Pointer类型。一旦您获得了功能映射,您就可以使事情变得更简单,更自动。

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