yannick818
yannick818

Reputation: 125

JNA return array of struct as parameter

I have a C function, which creates an array of structs

int createArray(myStruct** data_array);

From C I call the function like this:

myStruct* data_array;
int size = createArray(&data_array);

I want to call createArray in a similar way with JNA. I've generated the wrapper using JNAerator.

int createArray(myStruct.ByReference[] data_array);

I don't know what to pass to the JNA method createArray since data_array is actually a output parameter. I actually think the generated JNA method is wrong since I don't want to pass an array of myStruct, I want to receive one.

Shouldn't the parameter of the JNA method be PointerByReference?

Here are some tries that didn't worked for me

PointerByReference ptr = new PointerByReference();
int size = api.createArray(ptr); //Invalid memory access
myStruct.ByReference[] array = new myStruct.ByReference[10];
Arrays.fill(stLinks, new myStruct.ByReference()); //without this I get NullpointerException
int size = api.createArray(array); //Invalid memory access

Upvotes: 1

Views: 359

Answers (2)

Daniel Widdis
Daniel Widdis

Reputation: 9091

Shouldn't the parameter of the JNA method be PointerByReference?

Debugging this requires figuring out what exactly the native method does, which is likely documented in the API and not obvious from the method signatures.

PointerByReference allocates a pointer-sized block of memory on the Java side, and is generally the correct thing to pass when native is filling it with a value. After your clarification/answer it appears your invalid memory access was external to this code.

Your attempt to allocate an array of structures doesn't work because they require contiguous memory, which you need to allocate using toArray() if you're responsible for the allocation -- but it looks like you're not!

So you can pass a PointerByReference and extract its pointed-to (Pointer) value using getValue(). You could then use that pointer in a Structure constructor to populate the Java-side structure (array).

PointerByReference pbr = new PointerByReference();
int size = api.createArray(pbr);
MyStruct[] foo = (MyStruct[]) new MyStruct(pbr.getValue()).toArray(size);
// you may need to `read()` indices past 0 from this array

Upvotes: 1

yannick818
yannick818

Reputation: 125

Seems like the problem with Invalid memory access was caused by other side effects. I had to call other functions from the API before I can use createArray.

The working code is now:

PointerByReference ptr = new PointerByReference();
            
int size = api.createArray(ptr);
            
Pointer ptrToFirst = ptr.getValue();
myStruct firstElement = new myStruct(ptrToFirst);
myStruct[] array = (myStruct []) firstElement.toArray(size);

//Work with Array

api.deleteArray();          

Upvotes: 1

Related Questions