Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save poscat0x04/f7efef271bbd3af00842c061192a3e83 to your computer and use it in GitHub Desktop.
Save poscat0x04/f7efef271bbd3af00842c061192a3e83 to your computer and use it in GitHub Desktop.
What I learnd from writing alpm4h
This is a draft for a future blog post and might be deleted at any time.
Audiances are assumed to be familiar with the c2hs library and Haskell c ffi and have basic knowledge of c.
1. Overall design
I would suggest to do a two-layer design, that is one-level for binding and basic marshalling and one-level for abstraction.
2. Representing C datatypes in Haskell
When designing FFI, you almost always need to represent C datatypes as some Haskell datatypes. You'll need to further add Storable
instance for that Haskell type if you need to marshal between C and Haskell. Associating a C type with Haskell is relatively easy
with c2hs so I'll only cover the marshalling part.
enums are really simple since they are basically CInts, their storable instance can be automated with
TH(https://github.com/poscat0x04/alpm4h/blob/master/src/Foreign/ALPM/Internal/TH.hs)
structs without union inside are tricker but can be solved with the derive-storable which utilizes GHC.Generics
unions are a pain in the ass since C doesn't provide any tags to distinguish between each datatype. I failed to find any methods
other than manually writing the Storable instance.
3. Marshalling functions
(1) double pointers: double pointers can be handled with function hooks using "alloca-" and "peek*"
(2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment