direct mapping and returning a two dimension byte array

144 views
Skip to first unread message

Tobias Wolf

unread,
Jul 2, 2015, 8:46:59 AM7/2/15
to jna-...@googlegroups.com
I`ve the following direct method mapping:

static native byte[][] gk_EC_POINT_get_affine_coordinates(EC_GROUP group, EC_POINT point);

byte** gk_EC_POINT_get_affine_coordinates(EC_GROUP* group, EC_POINT* point);

JNA gives back the following error:

ava.lang.IllegalArgumentException: class [[B is not a supported return type (in method gk_EC_POINT_get_affine_coordinates in class com.tsystems.gematik.pkiprovider.GematikPKIProviderNative)
at com.sun.jna.Native.register(Native.java:1435)
at com.sun.jna.Native.register(Native.java:1396)

That means to me, that a two dimension array is not supported, right?
 No problem, I can change the method signature. But what is the best way to return a two dimensional array?

Timothy Wall

unread,
Jul 2, 2015, 3:35:19 PM7/2/15
to jna-...@googlegroups.com
Return a Pointer and then extract the info you need using the various Pointer methods based on you native memory layout.

Sent from my iPhone
--
You received this message because you are subscribed to the Google Groups "Java Native Access" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jna-users+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tobias Wolf

unread,
Jul 3, 2015, 2:32:25 AM7/3/15
to jna-...@googlegroups.com
I was already thinking about to use it as you proposed, for a single dimension array I think I know what to do:

Pointer.getByteArray(offset, arraySize)
                Pointer.getByteBuffer(offset, length)

By the way, how can I determine the length for the array? Must this a return parameter from native side or is there a jna function available?

But I`m wondering how I can extract a byte array of byte array e.g. byte[][] or byte**? I was already googling and looking here in the topics, but I didn`t found a proper answer what the best way is?
I understood that for performance reason I should use the nio.Buffer methods instead of using byte arrays to avoid coping of data between java and native side, right?

Timothy Wall

unread,
Jul 3, 2015, 2:51:40 AM7/3/15
to jna-...@googlegroups.com
The native side will have to tell you how big the buffer is, unless there's already an agreed upon size.

If the native side is one big block of data, regardless of whether it's conceptually an N dimensional array, it's more efficient to treat it as a one dimensional array and just figure out the appropriate offset (eg size*row+col or size*col+row).

Sent from my iPhone

Tobias Wolf

unread,
Jul 6, 2015, 8:40:22 AM7/6/15
to jna-...@googlegroups.com
What is the best way to declare a unsigned char* field within a struct? I tried with a nio.Buffer, but then I got the following error: Can't autogenerate a direct buffer on memory read

public static class ASN1_STRING extends Structure {
public int length;
public int type;
/** C type : unsigned char* */
public Buffer data;
/**
* The value of the following field depends on the type being<br>
* held. It is mostly being used for BIT_STRING so if the<br>
* input data has a non-zero 'unused bits' value, it will be<br>
* handled correctly
*/
public int flags;

public ASN1_STRING() {
super();
}

protected List<?> getFieldOrder() {
return Arrays.asList("length", "type", "data", "flags");
}

public ASN1_STRING(Pointer peer) {
super(peer);
}

public static class ByReference extends ASN1_STRING implements
Structure.ByReference {
};

Timothy Wall

unread,
Jul 6, 2015, 9:48:49 AM7/6/15
to jna-...@googlegroups.com
For generic buffers, just use `Pointer` (use `String` if it’s a NUL-terminated C string).
Reply all
Reply to author
Forward
0 new messages