简体   繁体   English

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

[英]JNA : Get value from a pointer to a pointer to a structure

I'm getting trouble with JNA about pointer to pointer problem.我在 JNA 上遇到了关于指针指针问题的问题。

Example structure:示例结构:

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

C method: 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;
}

A simple test in C: C中的一个简单测试:

int main() {
    PA a = NULL;
    test(&a);

    printf("%d\n", a->num);
    printf("%d", a->next->num);
}

JNA code 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 { }
}

Finally, I am trying to get the structure fields that was updated in C, but get "Invalid memory access"最后,我试图获取在 C 中更新的结构字段,但得到“无效的 memory 访问”

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
}

Any mistakes in my steps?我的步骤有什么错误吗?

When you get an "Invalid memory access" error you should start looking at when native memory allocations are done.当您收到“无效的 memory 访问”错误时,您应该开始查看本地 memory 分配何时完成。 Usually the API documents that (and tells you how to free it) and when not, you know it's your responsibility.通常 API 会记录(并告诉您如何释放它),如果没有,您知道这是您的责任。 In this case you can see in the C code you've posted, the allocation is done inside the test method:在这种情况下,您可以在您发布的 C 代码中看到,分配是在测试方法中完成的:

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

and

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

The problem here is that the Java side doesn't know about that allocation so you have to do it manually.这里的问题是 Java 端不知道该分配,因此您必须手动进行。

Your mapping of the function using a PointerByReference looks fine.您使用 PointerByReference 映射PointerByReference看起来不错。 While you can use getInt(0) on the return, you'd probably be better off at this point just instantiating the A structure from the returned pointer as you've done:虽然您可以在返回时使用getInt(0) ,但此时您最好只从返回的指针中实例化A结构,就像您所做的那样:

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

Then a.num should be your expected 123321. Then you have to take the returned pointer (to the native-allocated link) and use that to create another Java-side structure:那么a.num应该是您预期的 123321。然后您必须获取返回的指针(指向本机分配的链接)并使用它来创建另一个 Java 端结构:

A b = new A(a.next);

(You may want to just use a Pointer in the structure to make that part easy. If you use ByReference or A.ByReference then use getPointer() at this part.) (您可能只想在结构中使用Pointer来简化该部分。如果您使用ByReferenceA.ByReference ,则在此部分使用getPointer() 。)

At this point, I believe b.num should give you 456.在这一点上,我相信b.num应该给你 456。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM