Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
DevJac opened this issue Dec 19, 2019 · 1 comment

Comments

@DevJac
Copy link
Contributor

DevJac commented Dec 19, 2019

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
Copy link
Contributor

vmchale commented Jan 17, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants