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

Java JNA:从指向结构的指针的指针获取值,java,pointers,jna,Java,Pointers,Jna,我和JNA在指针对指针的问题上遇到了麻烦 示例结构: typedef struct _A { unsigned int num; struct _A *next; } A, *PA; A b = new A(a.next); C方法: void test(PA *a) { PA current = (PA) malloc(sizeof(A)); current->num = 123321; PA next = (PA) malloc(size

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

示例结构:

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

A b = new A(a.next);
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("%d\n", 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 { }
}
“我的步骤”中有错误吗?

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

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

这里的问题是,Java端不知道该分配,因此您必须手动执行

使用
PointerByReference
对函数进行映射看起来很好。虽然您可以在返回时使用
getInt(0)
,但此时您最好只从返回的指针实例化
A
结构,就像您所做的那样:

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

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

A b = new A(a.next);
(您可能只想在结构中使用
指针
,以简化该部分。如果您使用
ByReference
a.ByReference
,则在此部分使用
getPointer()


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

嘿@Daniel Widdis,真的非常感谢你帮助我,你指出的原因是合理的,但修复步骤同样不起作用。1.当我将映射更改为``void test(A)```时,A.num指向随机数,
next
字段get
null
.Hmm。不知道为什么它不起作用。本机代码正在分配内存,但Java端没有看到它。有几种方法可以做到这一点。你能发布你的更新代码吗?你可以在《谢谢》上看到修改后的java代码。好的,这是一个非常不寻常的API。我想我建议发送一个结构是错误的,因为我认为它会填充这个结构。事实上,您必须发送一个空指针(通过引用),因为本地代码进行分配。因此,我认为您之前的代码适用于指针/getInt部分。新的A()部件也相当不错。我认为您需要对从Next检索到的指针执行另一个新的A()。让我完全重写我的答案……这很有效,谢谢。我需要将
ByReference
字段更改为
Pointer
,以避免读取无效内存,因为我没有在C中将
next->next
的值设置为
NULL