[Haskell-cafe] libtiff

Duncan Coutts duncan.coutts at worc.ox.ac.uk
Tue Jan 17 15:46:55 EST 2006


On Tue, 2006-01-17 at 13:42 -0600, Green Bryan - bgreen wrote:
> Does anyone know of libtiff having been wrapped for Haskell?  If not,
> where could I find a good tutorial on wrapping a c library with
> functions that have variable argument parameters?

The Haskell FFI does not support calling "varargs" C functions. You
could write some C wrapper code that exposes just ordinary fixed arg
functions and call the vararg ones in the C wrapper.

How that wrapper code will work depends on just how 'variable' the
varargs functions you're wrapping are. If you can make do with just a
fixed number of variants then fine.

If there is no upper bound on the number of args then you're in a
difficult position. There is no portable way of constructing a va_list
type.

In your case I guess you're trying to bind:

int TIFFSetField(TIFF *tif, ttag_t tag, ...)
int TIFFGetField(TIFF *tif, ttag_t tag, ...)

Fortunately there are a limited number of tags, albeit rather a lot of
them. I'd suggest the best you can do is to write a C function that
takes a pointer to a C union of all the different possible tags. Then
your C function will switch on the tag, extract the values from the
union and call TIFFSetField/TIFFGetField appropriately.

For example:


union tfield {
  
  struct tfield_ARTIST {
    char** field1;
  };

  struct tfield_BADFAXLINES {
    uint32** field1;
  };

  /* etc for all 100ish tags */
};

/* our wrapper function */
int wrapper_TIFFSetField(TIFF *tif, ttag_t tag, tfield *field) {

  switch (tag) {
    case TIFFTAG_ARTIST:
      return TIFFSetField(tif, tag, field->tfield_ARTIST.field1)

    case TIFFTAG_BADFAXLINES:
      return TIFFSetField(tif, tag, field->tfield_BADFAXLINES.field1)

    /* etc */
  }l

};

The tfield can be constructed in Haskell using the Storable mechanism.

Hope this helps.

Duncan



More information about the Haskell-Cafe mailing list