javapythoncswigtypemaps

Using SWIG typemaps with java


I have successfully used the following typemap in a swig interface file where the target language is python:

%typemap(argout) track_t **phash_tracks {
  %append_output(SWIG_NewPointerObj(%as_voidptr(*$1), $*1_descriptor, SWIG_POINTER_OWN));
}

%typemap(in) track_t **phash_tracks (track_t *tracks) {
  // Alternatively, check if $input is a 0 integer `PyObject`...
  if ((SWIG_ConvertPtr($input, (void **) &tracks, $*1_descriptor, SWIG_POINTER_DISOWN)) == -1)
    tracks = NULL;
  $1 = &tracks;
}

However when I change the target language to java, I get a lot of compile time errors when I try and build the auto-generated c wrapper code that swig produces, i.e.

warning: implicit
      declaration of function 'SWIG_ConvertPtr' is invalid in C99 [-Wimplicit-function-declaration]
    if ((SWIG_ConvertPtr(jarg1, (void **) &tracks1, SWIGTYPE_p_track_t, SWIG_POINTER_DISOWN)) == -1)

error: use of undeclared
      identifier 'SWIG_POINTER_DISOWN'
    if ((SWIG_ConvertPtr(jarg1, (void **) &tracks1, SWIGTYPE_p_track_t, SWIG_POINTER_DISOWN)) == -1)

error: expected expression
    %append_output(SWIG_NewPointerObj(%as_voidptr(*arg1), SWIGTYPE_p_track_t, SWIG_POINTER_OWN));

and so on...

I noted that the code that gets pasted into the the swig wrapper code in the python case that contains the declarations of SWIG_ConvertPtr, SWIG_POINTER_DISOWN etc. comes from swigrun.swg

this is located in /usr/share/swig2.0/

This equivalent code is not pasted into the swig wrapper code when the target language is java. I'm not totally sure why thats not happening, as without it it can't compile due to all the missing declarations that the typemaps need.

Is something broken with my swig setup or am I suffering from a basic misunderstanding, something like you can't use typemaps with java or something like that?

I also noted in the c wrapper code for java, that the %append as in the interface file appeared verbatim in the auto-generated .c file, i.e. swig hadn't substituted it for anything. This also caused one of the many compile time errors..


Solution

  • The type system of Python is very different to Java, so the SWIG runtime is also different.

    From the manual:

    Java is one of the few non-scripting language modules in SWIG. As SWIG utilizes the type safety that the Java language offers, it takes a somewhat different approach to that used for scripting languages. In particular runtime type checking and the runtime library are not used by Java.

    You can still write typemaps for Java, but because of the strong typing they end up needing to be rather different and functions like SWIG_ConvertPtr simply don't exist as they aren't needed.

    If you write them right typemaps can be language agnostic, but once you start writing custom typemaps rather than relying on ones outside of the SWIG library it rapidly ceases to be generic. There's a trade-off between making generic interfaces with SWIG and interfaces that feel "right" to users of the target language too.