Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storable empty data declaration

Tags:

haskell

ghc

ffi

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?

like image 299
zmthy Avatar asked Jan 25 '11 14:01

zmthy


1 Answers

You can't allocate something if you don't know how big it is. Is the function just going to ignore its argument? Then pass in a null pointer. Otherwise, you need to actually allocate enough space for the struct - don't cut corners by allocating a zero-byte or pointer-sized buffer, as then the called function will write past the end of your buffer, corrupting memory.

Either finish the data declaration, or write a Storable instance with proper size and alignment values; there's no way around providing size/alignment data in some form.

like image 98
bdonlan Avatar answered Oct 27 '22 07:10

bdonlan