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>