MIT licensed by Mateusz Kloczko
Maintained by [email protected]
This version can be pinned in stack with:derive-storable-0.3.1.0@sha256:bd1c51c155a00e2be18325d553d6764dd678904a85647d6ba952af998e70aa59,2313
Depends on 1 package(full list with versions):
Used by 1 package in nightly-2024-10-31(full list with versions):

Introduction

Build Status

The derive-storable package allows you to automatically generate Storable instances for your datatypes. It uses GHC.Generics, which allows the coders to derive certain instances automatically. To derive a (G)Storable instance, the data-type has to:

  • ~~have only one constructor~~ There is now a sumtypes option for data-types with multiple constructors. See Sum types section for more.
  • all fields of the constructor need to be GStorable.
  • implement a Generic instance (derive (Generic))

Sum types

To enable support for sum types, add a -f sumtypes option to cabal new-build or cabal new-configure. The library discerns between sum and non-sum types. Non-sum types have the same memory layout as C structs, while sum types correspond to tagged unions:

struct datatype {
    unsigned char tag;
    union { 
        constructor1 a;
        constructor2 b;
        ...
    } val;
};

Note - while it is possible to have an instance for a self/mutually recursive data-type, using methods for the data-type will result in infinite loop. So there is no support for recursion in data-types.

Note on performance

There are some problems with performance of derived Storable instances. For now there exists a solution in form of GHC Core plugin - derive-storable-plugin.

Usage

Here’s an example:

{-# LANGUAGE DeriveGeneric #-}

import Foreign.Storable
import Foreign.Storable.Generic
import Foreign.Ptr
import Foreign.Marshal.Alloc

import Generics.Deriving

data Position = Position {
   x :: Double, 
   y :: Double
} deriving (Show,Read, Generic)

instance GStorable Position

updatePosition :: Ptr Position -> Position -> IO ()
updatePosition ptr pos = poke ptr pos


main = do
    let val = Position 0.0 10.0
    ptr <- malloc :: IO (Ptr Position)      
    putStrLn "Created a ptr with value of"
    putStrLn =<< show <$> peek ptr
    updatePosition ptr val
    putStrLn "And now the value of ptr is:"   
    putStrLn =<< show <$> peek ptr

Changes

Revision history for derive-storable

0.3.1.0 – 2021-04-13

0.3.0.0 – 2020-03-01

  • Removed instances module. A breaking change therefore bump to 0.3.

0.2.0.0 – 2020-03-01

  • Added support for sum types enabled through additional option.

0.1.2.0 – 2018-04-30

  • Added U1 instance for GHC.Generics.

0.1.1.1 rev1 – 2018-03-20

  • Bump to GHC 8.4.1

0.1.1.1 – 2017-10-05

  • Fixed a bug with POSIX types enabled on non POSIX systems.

0.1.1.0 – 2017-07-19

  • Bumped to GHC 8.2.*

0.1.0.6 – 2016-12-07

  • Made the information about performance problems more visible in README.md

0.1.0.4 – 2016-11-29

  • Fixed the bug with Foreign.Storable.Generic.Internal.Instances module.
  • Removed two tests related to numbering of fields.

0.1.0.3 – 2016-09-19

  • Changed the link in README to hackage repository.

0.1.0.2 – 2016-09-11

  • Changed generic-storable to derive-storable in README.md
  • Added README.md to the package

0.1.0.0 – 2016-09-08

  • First version. Released on an unsuspecting world.