[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