haskell / c2hs

c2hs is a pre-processor for Haskell FFI bindings to C libraries
http://hackage.haskell.org/package/c2hs
Other
198 stars 50 forks source link

C function takes `Color *` (a Color pointer), c2hs foreign import takes Ptr () #246

Open DevJac opened 4 years ago

DevJac commented 4 years ago

I have the following code in Lib.chs:

data Color = Color !Word8 !Word8 !Word8 !Word8 deriving (Show, Eq)

instance Storable Color where
  ...

#include "foo.h"

{# fun unsafe ClearBackground as ^ {with* %`Color'} -> `()' #}

During the build Lib.chs.c is generated by C2HS and contains:

#include "Lib.chs.h"
void __c2hs_wrapped__ClearBackground(Color * color)
{
    return ClearBackground(*color);
}

And Lib.hs is also generated by C2HS and contains, in part:

...
foreign import ccall unsafe "Lib.chs.h __c2hs_wrapped__ClearBackground"
  clearBackground'_ :: ((C2HSImp.Ptr ()) -> (IO ()))
...

Which results in the following type error:

src/Lib.chs:26:21: error:
    • Couldn't match type ‘Color’ with ‘()’
      Expected type: C2HSImp.Ptr ()
        Actual type: C2HSImp.Ptr Color
    • In the first argument of ‘clearBackground'_’, namely ‘a1'’
      In the first argument of ‘(>>)’, namely ‘clearBackground'_ a1'’
      In the expression: clearBackground'_ a1' >> return ()

The problem is that the generated C wrapper accepts a Color * (a Color pointer), but the "foreign import" tells Haskell that it accepts a Ptr (). It should be Ptr Color instead of Ptr () I believe, something like:

foreign import ccall "Lib.chs.h __c2hs_wrapped__ClearBackground"
  clearBackground'_ :: Ptr Color -> IO ()

A full (yet minimal) demo can be checked out from a repo I created: https://github.com/DevJac/c2hs-bug-demo

C2HS version:

C->Haskell Compiler, version 0.28.6 Switcheroo, 25 November 2017
  build platform is "x86_64-linux" <1, True, True, 1>

I'm using Cabal 3.0 and GHC 8.6.5.

vmchale commented 4 years ago

I think you want something like

data BzStream

{#pointer *bz_stream as BzStreamPtr -> BzStream #}

perhaps?

Here's an example of mine: https://github.com/vmchale/lzlib/blob/master/src/Codec/Lzip/Raw.chs#L87