FFI Help
Glynn Clements
glynn.clements@virgin.net
Wed, 4 Jun 2003 21:29:51 +0100
Malcolm Wallace wrote:
> > > > foreign import ccall "math.h signgam" signgamC :: IO Int
> >
> > signgam is an "int" variable, but this assumes that it is a function
> > of type "int signgam(void)".
> >
> > Write a C wrapper "int get_signgam(void) { return signgam; }" and
> > import that.
>
> Or alternatively, foreign import the address of the int and read it
> directly with 'peek'.
>
> import Foreign
> ...
> foreign import ccall "math.h &signgam" signgamC :: Ptr Int32
> ...
> gammaIO :: Double -> IO Double
> gammaIO x = do lg <- lgammaC x
> s <- peek signgamC
> return $ fromIntegral s * exp lg
One potential drawback with that approach is that an implementation
might decide to add thread-safety, in the same manner as glibc does
with errno:
# if !defined _LIBC || defined _LIBC_REENTRANT
/* When using threads, errno is a per-thread value. */
# define errno (*__errno_location ())
# endif
[where __errno_location() returns a thread-specific location via
pthread_getspecific().]
OTOH, a C wrapper will cope with whatever contortions the libc
developers decide to use.
--
Glynn Clements <glynn.clements@virgin.net>