Let's get this finished
simonmar at microsoft.com
Thu Jan 4 05:59:05 EST 2001
> The reason that I don't like MarshalUtils as it is are the
> (1) It isn't H98 and in fact its interface cannot be
> implemented with H98. The problem are the routines
> with signatures in patterns:
> malloc :: Storable a => IO (Ptr a)
> malloc :: IO (Ptr a) = mallocBytes (sizeOf (undefined::a))
> alloca :: Storable a => (Ptr a -> IO b) -> IO b
> alloca (act :: Ptr a -> IO b) = allocaBytes (sizeOf
> (undefined::a)) act
How about this:
malloc :: Storable a => IO (Ptr a)
malloc = res
where res = mallocBytes (sizeOf (unsafePerformIO
The result type signatures are just a convenient (and much more
readable) way to write these functions.
> (2) pokeArray, peekArray, etc are really part of what should
> go into the high-level marshalling.
Ok. Actually I consider the current libraries to be on the verge of
usability, modulo the missing string marshalling and error
> The Marshal modules
> I propose the following set of modules:
> - MarshalAlloc:
> The allocation routines that are in MarshalUtils now,
> but modified as outlined above.
> - MarshalArray:
> The array marshalling routines
> - MarshalString:
> Most people seem to be of the opinion that we have to
> handle strings specially due to Unicode conversion
> requirements. So, this is were string marshalling goes.
I've been wondering whether we should have something like
newtype CString = CString (Ptr CChar)
which would allow GHC to replace the representation with a ByteArray
leading to a much more efficient implementation of withCString. There
are other reasons why having a special CString type might be a good
idea: a C string really is more than just a pointer to char, it is an
array with a zero terminator and is specified in some kind of encoding.
Having a special CString type would provide more type safety.
One problem with the optimisation is that GHC can't handle ByteArrays
being *returned* from a foreign function.
> - MarshalError:
> Combinators to test for common error conditions. The
> main open problem here is the handling of errno, I
> - MarshalConv:
> The C2HS IntConv, BoolConv, etc classes. Marcin just
> uses `fromIntegral' here, but I think that this is too
> limited - eg, it doesn't handle Bool.
Could you explain the motivation for these? I can see the need for some
way to convert Bool<=>CInt (which is defined by ISO C), but can't the
others be just fromIntegral?
> soemthing along the C2HS ToAddr/FromAddr classes, but it
> probably makes to have `stdArrayPtr' etc as additional
> member functions (this is similar to the newXXX routines
> that are in MarshalUtils now, but with additional
> overloading). Furthermore, Marcin-syle withXXX routines
> would fo here.
I'm not sure how ToAddr/FromAddr would work. From looking at C2HS, they
seem to provide a consistent interface to marshalling that is specific
to a given Haskell type. I haven't found a need for something like this
in my own code yet, so again could you motivate?
> - MarshalUtils:
> The memcpy/memmove stuff, indexPtr (if it still makes
> sense), and whatever else doesn't get its own module.
> I think, we should leave C2HS's marshX routines out. We
> discussed how to make them arity independent for quite a
> while and AFAIR, there wasn't a really good proposal.
> Finally, all the above modules should be jointly exported by
> a module `Marshal'.
More information about the FFI