[Haskell-cafe] Calling a C function that returns a struct by value

Nick Bowler nbowler at elliptictech.com
Wed May 25 23:14:54 CEST 2011


On 2011-05-25 16:19 -0400, Matthew Steele wrote:
>  From Haskell, I want to call a C function that returns a struct by  
> value (rather than, say, returning a pointer).  For example:
> 
>    typedef struct { double x; double y; } point_t;
>    point_t polar(double theta);
> 
> I can create a Haskell type Point and make it an instance of Storable  
> easily enough:
> 
>    data Point = Point CDouble CDouble
>    instance Storable Point where -- insert obvious code here

Note that there may be an arbitrary amount of padding bytes between the
two members of your struct, as well as after the last member, so
defining this Storable instance portably is somewhat tricky and
non-obvious.

> And now I want to do something like this:
> 
>    foreign import ccall unsafe polar :: CDouble -> IO Point
> 
> ...but that doesn't appear to be legal (at least in GHC 6.12).  Is  
> there any way to import this C function into Haskell _without_ having  
> any additional wrapper C code?

No, the Haskell FFI simply cannot describe C functions with struct
parameters or return values.  You will need to call this function with a
C wrapper.

Assuming you got the Storable instance correct, something like

  void wrap_polar(double theta, point_t *out)
  {
     *out = polar(theta);
  }

should do nicely.  Alternately, you can avoid the tricky business of
defining a Storable instance for your struct entirely with something
like:

  void wrap_polar(double theta, double *x, double *y)
  {
     point_t tmp = polar(theta);
     *x = tmp.x;
     *y = tmp.y;
  }

Cheers,
-- 
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)



More information about the Haskell-Cafe mailing list