Returns an array of Java objects using SWIG

I am writing a JNI wrapper for a C ++ library using SWIG. One of the methods in the library returns an array of structures in allocated memory:

typedef struct {
    int id;
    double x;
    double y;
} DataStruct;

int get_all_data ( long ref, DataStruct **ppdata, size_t *psize ) {
    // ... prepare the data by the ref
    *ppdata = (DataStruct*) malloc(sizeof(DataStruct) * size);
    *psize = size;
    return 0;
}

The method signature in java should look something like this:

 native DataStruct[] get_all_data(long ref);

Thus, I expect SWIG to create a java DataStruct in java and a wrapper that will call the library method, and then create a jarray DataStruct in the JVM and populate it with DataStruct objects initialized from the DataStruct structures returned by the library, and finally free the allocated memory indicated ppdata.

I’ve been trying to wrap my head in styles like SWIG for some time now, and the only solution I can see right now is to use the% native directive and create the JNI implementation completely manually. Can I get at least some help from SWIG in this case?

+4
1

, , . -, , multi arguments , . -, , argout .

SWIG , C (JNI) Java, . :

%module test

%{
#include <assert.h>
%}

%typemap(in,numinputs=0) (DataStruct **ppdata, size_t *psize) (size_t tempsize, DataStruct *tempdata) %{
  $2 = &tempsize;
  $1 = &tempdata;
%}

%typemap(jtype) int get_all_data "long[]";
%typemap(jstype) int get_all_data "DataStruct[]";
%typemap(javaout) int get_all_data {
    final long[] arr = $jnicall;
    DataStruct[] ret = new DataStruct[arr.length];
    for (int i = 0; i < arr.length; ++i) {
      ret[i] = new DataStruct(arr[i], false);
    }
    return ret;
  }

%typemap(jni) int get_all_data "jlongArray";

%typemap(out) int get_all_data %{
  // Handle errors in the int return value ($1)
  assert(!$1);
%}

%typemap(argout) (DataStruct **ppdata, size_t *psize) {
  $result = JCALL1(NewLongArray, jenv, *$2);
  jlong temparr[*$2];
  for (size_t i = 0; i < *$2; ++i) {
    *(DataStruct**)&temparr[i] = &((*$1)[i]);
  }
  JCALL4(SetLongArrayRegion, jenv, $result, 0, *$2, temparr);
}

%inline %{
typedef struct {
    int id;
    double x;
    double y;
} DataStruct;

int get_all_data ( long ref, DataStruct **ppdata, size_t *psize ) {
    static const size_t size = 4;
    *ppdata = (DataStruct*) malloc(sizeof(DataStruct) * size);
    *psize = size;
    for (size_t  i = 0; i < size; ++i) {
      DataStruct val = {i,i,i};
      (*ppdata)[i] = val;
    }
    return 0;
}
%}

:

  • get_all_data . , DataStruct, - DataStruct, .
  • , .
  • , Java. , , . SWIG - , -. Java , sizeof, , , . ( , , , , , ).

:

public class run {
  public static void main(String[] argv) {
    System.loadLibrary("test");
    DataStruct[] result = test.get_all_data(0);
    for (int i = 0; i < result.length; ++i) {
      System.out.println(result[i].getId());
    }
  }
}

:

swig2.0 -Wall -java -c++ test.i
gcc -Wall -Wextra -shared -o libtest.so -I/usr/lib/jvm/default-java/include -I/usr/lib/jvm/default-java/include/linux test_wrap.cxx
javac run.java
LD_LIBRARY_PATH=. java run
0
1
2
3
+3

All Articles