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/)

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to