[Haskell-cafe] c2hs seems to ignore the types I give it when generating foreign import declarations

Manuel M T Chakravarty chak at cse.unsw.edu.au
Sun Dec 11 09:50:43 EST 2005


Cale Gibbard:
> Hello, I've just started writing bindings to the Enlightenment
> Foundation Libraries, using c2hs. I've run into the following problem
> with the types in the foreign import declarations generated.
> 
> In Imlib2.h, there is a function prototype:
> int imlib_get_visual_depth(Display * display, Visual * visual);
> 
> In Imlib.chs, I have (among other things)
> import qualified Graphics.X11.Xlib.Types as Xlib
> -- ...
> {# fun imlib_get_visual_depth as getVisualDepth { id `Xlib.Display',
> id `Xlib.Visual' } -> `Int' #}
> 
> I run:
> c2hs -k /usr/local/include/Imlib2.h Imlib.chs
> 
> and in the resulting Imlib.hs, I get:
> 
> --- this part is correct:
> getVisualDepth :: Xlib.Display -> Xlib.Visual -> IO (Int)
> getVisualDepth a1 a2 =
>   let {a1' = id a1} in
>   let {a2' = id a2} in
>   getVisualDepth'_ a1' a2' >>= \res ->
>   let {res' = cIntConv res} in
>   return (res')
> 
> --- this part is not:
> foreign import ccall safe "Imlib.h imlib_get_visual_depth"
>   getVisualDepth'_ :: ((Ptr ()) -> ((Ptr ()) -> (IO CInt)))
> 
> Why did it choose the type Ptr (), when I gave the type Xlib.Display?
> I could do an additional cast, but it will get tedious, as I have a
> lot of functions to import, and there shouldn't be any need for it
> anyway. As this is, it doesn't typecheck at all. If by hand, I change
> it to read:
> 
> foreign import ccall safe "Imlib.h imlib_get_visual_depth"
>   getVisualDepth'_ :: Xlib.Display -> Xlib.Visual -> IO CInt
> 
> (which is what I expected it to produce in the first place) then it
> works as expected.
> 
> Am I making a grievous error, or is this a bug/lack of a feature?

You need to tell c2hs to what Haskell type a C pointer type maps before
it can generate the right signature for the import declaration.  This is
done using a pointer hook:

  http://www.cse.unsw.edu.au/~chak/haskell/c2hs/docu/c2hs-3.html#ss3.10

In your case, you would usually do

  {#pointer *Display as Display newtype#}

However, when you use this form, c2hs will generate the newtype
declaration for you that you import from `Graphics.X11.Xlib.Types' (and
you would have to cast between your version of `Display' and that of
`Xlib').

Are you actually going to use functions from `Graphics.X11.Xlib' on
these types or did you just want to use the existing types because it is
more elegant?  It is a awkward to use existing types that have *not*
been generated by c2hs in that way at the moment.  However, it should be
quite easy to extend c2hs to enable this quite easily if it is
important.

Manuel

PS: I started a binding of Ecore and Evas a while ago.  Still 
    incomplete, but if you meant to do these, too, then we should maybe 
    exchange code instead of duplicating work.




More information about the Haskell-Cafe mailing list