fengye87
fengye87

Reputation: 2553

SWIG:how to deal with pointers in generated Java code

I'm using SWIG to generate Java binding for one of my C lib. But I'm having trouble to deal with C pointers. Here's some code to demonstrate my problem:

The calc.h file:

extern int sum(int a, int b);
extern int sum_1(int *a, int *b);

The calc.c file:

#include "calc.h"

int sum(int a, int b) {
  return a + b;
}

int sum_1(int *a, int *b) {
  return *a + *b;
}

The calc.i file:

%module calc
%{
#include "calc.h"
%}

%include "calc.h"

I use the following command to generate the Java binding code:

gcc -c calc.c
swig -java calc.i
gcc -fpic -c calc_wrap.c -I/usr/lib/jvm/java-1.8.0/include -I/usr/lib/jvm/java-1.8.0/include/linux
ld -G calc_wrap.o calc.o -o libcalc.so

Now for my main func:

public class Application {
  static {
    System.loadLibrary("calc");
  }

  public static void main(String[] args) {
    System.out.println(calc.sum(1, 2));
    // System.out.println(calc.sum_1(?, ?));
  }
}

The above code would compile & run normally and print out 3 as expected. The problem is, how to use the calc.sum_1 func? I'm totally lost about how to deal with int * type.

FYI, attached some code generated by SWIG:

The calc.java file:

public class calc {
  public static int sum(int a, int b) {
    return calcJNI.sum(a, b);
  }

  public static int sum_1(SWIGTYPE_p_int a, SWIGTYPE_p_int b) {
    return calcJNI.sum_1(SWIGTYPE_p_int.getCPtr(a), SWIGTYPE_p_int.getCPtr(b));
  }

}

The calcJNI.java file:

public class calcJNI {
  public final static native int sum(int jarg1, int jarg2);
  public final static native int sum_1(long jarg1, long jarg2);
}

The SWIGTYPE_p_int.java file:

public class SWIGTYPE_p_int {
  private transient long swigCPtr;

  protected SWIGTYPE_p_int(long cPtr, @SuppressWarnings("unused") boolean futureUse) {
    swigCPtr = cPtr;
  }

  protected SWIGTYPE_p_int() {
    swigCPtr = 0;
  }

  protected static long getCPtr(SWIGTYPE_p_int obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }
}

Really appreciate your help!

Upvotes: 1

Views: 1078

Answers (1)

Jorn Vernee
Jorn Vernee

Reputation: 33905

Swig doesn't generate a way to create pointers by default, but there are several ways described here: http://web.mit.edu/svn/src/swig-1.3.25/Examples/java/pointer/index.html

For instance, add this to the bottom of the interface file:

%include cpointer.i
%pointer_functions(int, intp);

Which generates a set of utility functions to create SWIGTYPE_p_int with:

SWIGTYPE_p_int p1 = calc.new_intp();
SWIGTYPE_p_int p2 = calc.new_intp();
calc.intp_assign(p1, 1);
calc.intp_assign(p2, 2);

System.out.println(calc.sum_1(p1, p2));

calc.delete_intp(p1);
calc.delete_intp(p2);

Upvotes: 3

Related Questions