Haskell C FFI: accessing static data structures Haskell C FFI: accessing static data structures c c

Haskell C FFI: accessing static data structures


John L. suggested the CApiFFI extension, which does exactly what I want: allows you to import values rather than locations. Now:

{-# LANGUAGE CApiFFI #-}newtype {-# CTYPE "foo.h" "struct foo_struct" #-} Foo = Foo { getFoo :: (Ptr Foo) }foreign import capi "foo.h value FOO_GEORGE" fooGeorgePtr :: Ptr afooGeorge = Foo fooGeorgePtr

Another advantage is that this works regardless of whether FOO_GEORGE is a C variable or a preprocessor macro. The C API I’m working with uses both, and different implementations of the same API that I link to do so differently, so being independent of that is great.

However, there’s a stumbling block: CApiFFI doesn’t work with ghci! The problem is known, and it isn’t slated to be fixed until GHC 8.0.1 (when I first wrote this, it was due for 7.10, and then was pushed forward). I have a very hacky workaround. CApiFFI works by generating a C library on the fly, compiling and linking the Haskell program against it. It removes the library when done; the ghci problem seems to be that the .so file is gone by the time ghci needs to link against it. I just grab the .c file during compilation before it gets deleted, then compile it myself and tell ghci to load it. Since I don’t change that portion of the program very often, it works out for me well enough.

My method for catching the temporary .c file is to start ghci in Emacs compilation-mode, with (setq compilation-auto-jump-to-first-error t). Emacs sees the error and loads the .c file into a buffer before GHC gets around to deleting it — by the time I see it the file is gone, but I’ve got the contents in a buffer.

Update: ghci -fobject-code Foo works, but can only see the names exported from the module.