[Gdal-dev] Ready to commit first batch of swig-java changes

Tamas Szekeres szekerest at gmail.com
Sun Mar 25 16:48:41 EDT 2007


2007/3/25, Andrea Aime <aaime at openplans.org>:
> Tamas, I've committed my changes as of revision 11607.
> I did not change them thought. The rationale is, I'm not sure changing
> the typemaps would be side effect free.
> The typemap for wkb functions involves handling "int nLen, char *pBuf"
> as a byte[] in Java, because chars in java are a 16bit data type.
> Now, changing the typemap directly in typemaps_java.i may impact other
> functions in the gdal bindings and I'm not sure this would be good (it
> may be the right thing to do, but I did not have the time to check).
> Doing it locally would mean temporary overriding the general one,
> but in fact, once you've overridden a general typemap, how do you
> reistall the old one?
> I accept suggestions :-)

Andrea,

Typemaps in SWIG has a global scope so redefining a particular typemap
will implicitly %clear the previous definition. So if you don't want
to accidentally impact the existing code you might want to create a
specific typemap for this case and use the %apply %clear statements
for the corresponding code.
The C# interface works this way in many areas. For the generic buffer
pointers I'm using the 'void* buffer_ptr' typemap as:

%typemap(imtype, out="IntPtr") void *buffer_ptr "IntPtr"
%typemap(cstype) void *buffer_ptr %{IntPtr%}
%typemap(in) void *buffer_ptr %{ $1 = ($1_ltype)$input; %}
%typemap(out) void *buffer_ptr %{ $result = $1; %}
%typemap(csin) void *buffer_ptr "$csinput"
%typemap(csout, excode=SWIGEXCODE) void *buffer_ptr {
      IntPtr ret = $imcall;$excode
      return ret;
}

Whenever I want to use it I can apply the typemap as:

#ifdef SWIGCSHARP
%apply (void *buffer_ptr) {char *wkb_buf};
#endif
  %feature("kwargs") OGRGeometryShadow;
  OGRGeometryShadow( OGRwkbGeometryType type = wkbUnknown, char *wkt =
0, int wkb= 0, char *wkb_buf = 0, char *gml = 0 ) {
    if (type != wkbUnknown ) {
      return (OGRGeometryShadow*) OGR_G_CreateGeometry( type );
    }
    else if ( wkt != 0 ) {
      return CreateGeometryFromWkt( &wkt );
    }
    else if ( wkb != 0 ) {
      return CreateGeometryFromWkb( wkb, wkb_buf );
    }
    else if ( gml != 0 ) {
      return CreateGeometryFromGML( gml );
    }
    // throw?
    else return 0;
  }
#ifdef SWIGCSHARP
%clear char *wkb_buf;
#endif

For the C# interface it's not enough to create a typemap for mapping
the buffer pointer, some kind of marshalling code should also be
created between the managed and unmanaged code. Therefore I'm often
following the policy to map the buffer pointer to IntPtr natively, and
create some overloads including the marsalling code using the cscode
typemap. At some point these overloads are eventually calling the
generic (mapped) version. This solution gives the free hand for the
user to decide whether she want to implement her own marshaler or rely
on the code provided by this interface.

Geneally I couldn't really alter the number of the parameters using
multi argument typemaps. I seems that the type of the first parameter
can only be controlled and for the C# language it was not implemented
completely.

I've recently implemented the wkb based geometry creation in some way,
but it might differ from your implementation regarding to the language
specifics mentioned before.

I hope I could help, anyway.
You can also contact me (szekerest) on #gdal if you have further issues.


Best regards,

Tamas



More information about the Gdal-dev mailing list