I have a C function like this:
void get_data(const obj_t *obj, short const **data, int *data_len);
I wrote it like this specifically for Swig, since
const short *get_data(const obj_t *obj, int *data_len);
causes trouble, as SWIG’s typemaps aren’t smart enough to associate the data_len with the return value.
In Java I want to be able to call this function like this:
short data[]= mylib.get_data(obj);
But I can’t figure out how to get the array output parameter to become a return value. With Ruby and Python this works fine, as SWIG for those languages supports returning output params as return values (since the languages can have multiple return values).
How can I get this to work with Java?
I’ve put together the following test header file to demonstrate the problem:
I’ll talk through the module file I wrote, it starts pretty standard:
Then we set up a typemap for the
data_lenargument. It doesn’t need to be visible on the Java side since the length will be known by the array, but we do need to arrange some storage for the pointer to point to and we make sure it lasts long enough that we can read it later when returning the array to Java too.Then we want SWIG to use
short[]on the Java side for the return type:and
jshortArrayin the JNI side – there’s no need to construct a proxy type, so we just pass the returned value straight through:Finally we create a typemap that’s going to create a new array, with size based on the length returned from the function and copy the returned result into the Java array for us. If needed we should
free()the real result array here, but in my example it was statically allocated so didn’t need to be freed.Finally we include the header file for SWIG to wrap, using the typemaps we just wrote:
I tested this with:
Which produced:
For reference you could have wrapped:
also though if your function had a way to query the size without setting the array you could wrap this slightly smarter by allocating an array of the correct size on the Java side. To do this you’d want to to write an intermediate function in Java that queried the size, set up the call and then returned the resulting array. This would allow you to use
GetShortArrayElements/ReleaseShortArrayElementsfor a potentially 0 copy call.This would work because arrays in Java are basically passed by reference, e.g.: