我有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。
答案 0 :(得分:0)
number
和word
必须是公共字段。该错误消息表明JNA找不到与您在getFieldOrder()
中声明的名称相对应的相应字段; Structure
的字段必须是公共成员,如果您希望它们映射到等效的本地字段。
<强>更新强>
你的getFieldOrder()
(在任一课程中)都不会编译。
此外,您的原生函数aFunction
会返回struct*
,这意味着它绝对应该不使用Structure.ByValue
作为返回类型。
你应该返回一个Pointer
(如果你需要处理内存)或只是一个从Structure
派生的返回类型(Structure.ByReference
暗示了返回类型)。
通常在使用JNA时,如果您不熟悉指针和结构解除引用,则应使用Pointer
类型。一旦您获得了功能映射,您就可以使事情变得更简单,更自动。
请参阅FAQ以了解应如何映射各种指针和数组变体。