I created a test case that reflects what you are trying to do (I think):
#include <stdlib.h> enum thing { ONE=1, TWO=2, THREE=3 }; static signed char *get_data(enum thing t, size_t *len) { *len = (size_t)t; signed char *ret = malloc(sizeof(signed char) * (*len)); for (size_t i = 0; i < *len; ++i) { ret[i] = i; } return ret; }
To wrap get_data() , I used the following interface:
%module test %{ #include "test.h" %} %typemap(jni) signed char *get_data "jbyteArray" %typemap(jtype) signed char *get_data "byte[]" %typemap(jstype) signed char *get_data "byte[]" %typemap(javaout) signed char *get_data { return $jnicall; } %typemap(in,numinputs=0,noblock=1) size_t *len { size_t length=0; $1 = &length; } %typemap(out) signed char *get_data { $result = JCALL1(NewByteArray, jenv, length); JCALL4(SetByteArrayRegion, jenv, $result, 0, length, $1); } %include "test.h"
This basically means that the return type from the get_data function is a Java array directly from the JNI code completely through the SWIG proxy. After that, it sets a temporary size_t called length , which will be used to call the real C function and save the result. (I did not see noblock , before I saw this answer to another question , it tells SWIG not to make the typemap argument independent and, as such, could be one size_t *len parameter for this function, take a look at what it does with created wrapper code if you're interested).
After this set, it remains only to select the array using a JNI call and copy some values ββinto it.
I tested this with:
public class run { public static void main(String[] argv) { System.loadLibrary("test"); byte[] test1 = test.get_data(thing.ONE); System.out.println(test1.length); System.out.println(test1 + ": " + test1[0]); byte[] test2 = test.get_data(thing.TWO); System.out.println(test2.length); System.out.println(test2 + ": " + test2[0] + ", " + test2[1]); byte[] test3 = test.get_data(thing.THREE); System.out.println(test3.length); System.out.println(test3 + ": " + test3[0] + ", " + test3[1] + ", " + test3[2]); } }
Which then gave:
one
[ B@525483cd : 0
2
[ B@2a9931f5 : 0, 1
3
[ B@2f9ee1ac : 0, 1, 2
I changed a bit by making my signed char . If you want to do this unsigned, you need to either use casting (beware of losing the sign at best), or short / int with the appropriate conversion.
Be careful about owning memory in your real code.