JNA:从指向结构的指针中获取值



我在JNA的指针到指针问题上遇到了麻烦。

示例结构:

typedef struct _A {
unsigned int num;
struct _A *next;
} A, *PA;

C方法:

void test(PA *a) {
PA current = (PA) malloc(sizeof(A));
current->num = 123321;
PA next = (PA) malloc(sizeof(A));
next->num = 456;
current->next = next;
*a = current;
}

一个简单的C:测试

int main() {
PA a = NULL;
test(&a);
printf("%dn", a->num);
printf("%d", a->next->num);
}

JNA代码

public interface DLLLibrary extends Library {
......
void test(PointerByReference a);
}
public class A extends Structure {
public int num;
public ByReference next;
public A() {
super();
}
protected List<String> getFieldOrder() {
return Arrays.asList("num", "next");
}
public A(Pointer peer) {
super(peer);
}
public static class ByReference extends A implements Structure.ByReference { }
public static class ByValue extends A implements Structure.ByValue { }
}

最后,我试图获得在C中更新的结构字段,但得到了";无效存储器访问";

public static void main(String[] args) {
PointerByReference pointer = new PointerByReference();
DLLLibrary.INSTANCE.test(pointer);
assert pointer.getValue().getInt(0) == 123321; //this works
A a = new A(pointer.getValue());
//assert a.next.num == 456;  //excepted action
a.read(); //java.lang.Error: Invalid memory access
}

我的步伐有错吗?

当你得到一个"无效存储器访问";当本机内存分配完成时,您应该开始查看错误。通常API会记录(并且告诉如何释放它(,如果没有,你知道这是你的责任。在这种情况下,你可以在你发布的C代码中看到,分配是在测试方法中完成的:

PA current = (PA) malloc(sizeof(A));

PA next = (PA) malloc(sizeof(A));

这里的问题是Java方面不知道该分配,所以您必须手动执行。

使用PointerByReference映射函数看起来不错。虽然您可以在返回时使用getInt(0),但在这一点上,您可能会更好地从返回的指针实例化A结构,就像您所做的那样:

A a = new A(pointer.getValue());

那么a.num应该是您期望的123321。然后,您必须获取返回的指针(指向本机分配的链接(,并使用它来创建另一个Java端结构:

A b = new A(a.next);

(您可能只想在结构中使用Pointer来简化该部分。如果您使用ByReferenceA.ByReference,则在此部分使用getPointer()。(

在这一点上,我认为b.num应该给你456。

最新更新