I am trying to write a Haskell program that communicates with C (ultimately for iOS via GHC-iOS). I want it to pass a string from C to Haskell, have Haskell process it and then return some Data types from Haskell to C Structs via hsc2s. I have been unsuccessful at finding a clear, simple tutorial. The only thing Haskell needs from C is the String, nothing else.
I have no trouble with the very first part, passing a string to Haskell.
testPrint :: CString -> IO ()
testPrint c = do
s <- peekCString c
putStrLn s
For test purposes and future reference, I just want to be able to handle something like the following.
C Struct
struct testdata {
char *a;
char *b;
int c;
};
Haskell Data Type
data TestData = TestData {
a :: String,
b :: String,
c :: Int
} deriving Show
-- not sure what the type would look like
testParse :: CString -> TestData
I understand that I need to typeclass TestData as Storable and implement peek, poke, sizeOf and alignment, but I need to see a simple example before I can really understand it. Most of the tutorials require outside libraries and make it more complicated than it needs to be.
Here are the resources I've looked at:
Stackoverflow - How to use hsc2hs to bind to constants, functions and data structures?
Haskell Cafe - FFI for a beginner
Writing Haskell interfaces to C code: hsc2hs
Edit: Currently where I am stuck (gets segmentation error when setFoo is called in C)
Haskell Code Snippet
instance Storable Foo where
sizeOf = #{size foo}
alignment = alignment (undefined :: CString)
poke p foo = do
#{poke foo, a} p $ a foo
#{poke foo, b} p $ b foo
#{poke foo, c} p $ c foo
peek p = return Foo
`ap` (#{peek foo, a} p)
`ap` (#{peek foo, b} p)
`ap` (#{peek foo, c} p)
foreign export ccall "setFoo" setFoo :: Ptr Foo -> IO ()
setFoo :: Ptr Foo -> IO ()
setFoo f = do
newA <- newCString "abc"
newB <- newCString "def"
poke f (Foo newA newB 123)
C Code Snippet
foo *f;
f = malloc(sizeof(foo));
foo->a = "bbb"
foo->b = "aaa"
foo->c = 1
// this is incorrect
// setFoo(&f);
// this is correct
setFoo(f);
This is a complete example of a C program that passes a struct to Haskell then Haskell mutates the values of that struct. It has no outside dependencies. You should be able to copy the code and run it if you have GHC. Hopefully this will serve as a simple, straightforward example for others.
Foo.h
Foo.c
HsFoo.hsc
main.c
Command Line - Compile files and run