I'm attempting to create a Haskell wrapper for a C library. The underlying structs are too complicated to express as explicit types, and I don't actually use them other than for passing between C functions, so I'm using EmptyDataDecls
to let GHC work it out for me.
What I need is a pointer to one of these data types, but when I attempt to create one with alloca
it complains that the data is not of the type Storable
. For example:
{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}
module Main where
import Foreign.Marshal.Alloc
import Foreign.Ptr
data Struct
foreign import ccall "header.h get_struct"
get_struct :: Ptr Struct -> IO ()
main = alloca $ \ptr -> get_struct ptr
GHC won't compile this, saying there's no instance for Storable Struct
. I could implement it myself:
instance Storable Struct where
sizeOf _ = ...
alignment _ = ...
But that comes close to defeating the purpose - I don't want to have to define such things if I don't care what's in the struct.
I've noticed that a pointer to a pointer works fine, because the Ptr
class is Storable
. So I can accomplish what I'm aiming for by using peek
on ptr
before calling get_struct
:
main = alloca $ \ptr -> do
ptr <- peek ptr
get_struct ptr
This feels like a hack, though.
Is there a way to get empty data declarations to be considered Storable
without defining an instance?