javastructurejnajnaerator

How to pass PointerByReference adress to a structure in JNA


i would have a question regarding the following source, i simplified it to make it a bit easier to understand it.

c code

struct test
{
int test1;
};

int create_context(test **context); 
int use_context(test *context);

java code

public static class test extends Structure {
    public int test1;
    public test() {
        super();
    }
    public test()(Pointer p) {
        super(p);
    }
    protected List getFieldOrder() {
        return Arrays.asList("test1");
    }
    public test(int test1) {
        super();
        this.test1 = test1;
    }
    public static class ByReference extends test implements Structure.ByReference {

    };
    public static class ByValue extends test implements Structure.ByValue {

    };
}
public static native int create_context(PointerByReference context);
public static native int use_context(TestLibrary.test context);

I access the structure in java like this,

    PointerByReference contextPointer = new PointerByReference();
    int status = INSTANCE.create_context(contextPointer);
    test context = new test(contextPointer.getValue());
    status = INCTANCE.use_context(context);

When I debugged this in visual studio, i have seen, that for create_context und use_context different memory adresses are used. When i set the the int test1 value, it is right, but I´am wondering, why the adresse of context is different. Does anyone has an Idea? Wouldn´t that led to an memory problem? Or any Idea what I´am doing wrong? Thanks Valentina


Solution

  • You hav chosen the convention of generally using struct test*, so we'll work with that.

    Your native code needs to look like this:

    int create_context(struct test **context) {
        *context = (struct test *)malloc(sizeof(test));
        // initialize here...
        return 0;
    }
    

    When you call create_context, you must pass in the address of a pointer:

    struct test* test_ptr;
    
    create_context(&test_ptr);
    
    test_ptr->some_field = ...; // operate on your struct via pointer
    

    It's important to keep straight when you're using the structure by value (struct test), by reference (struct test*), or the address of your reference (struct test**). Whether your usage is in C or in Java, the concepts are the same.