[racket] FFI: Giving a double pointer to a function

From: Ryan Culpepper (ryan at cs.utah.edu)
Date: Sun Dec 2 20:23:51 EST 2012

Based on the documentation I found and the CP_ARBITER_GET_SHAPES macro, 
it looks like the double-pointer arguments are just used for multiple 
outputs. So you should use the following type for the function:

(_fun _cpArbiter-pointer
       (out1 : (_ptr o _cpShape-pointer))
       (out2 : (_ptr o _cpShape-pointer))
       -> _void
       -> (values out1 out2))

The FFI takes care of allocating the necessary temporary space that the 
function writes into. The Racket-side function takes just one argument 
(for the arbiter), and it returns two _cpShape-pointer values. So you 
would use it like this:

   (let-values ([(water poly) (cpArbiterGetShapes arb)])
     ___
     (let ([count (cpPolyShapeGetNumVerts poly)])
       ___))

Does that work?

Ryan


On 12/02/2012 07:59 PM, Vince Kuyatt wrote:
> So I recently started to poke at my humble little bindings to the
> Chipmunk library again. (someone sent me an email asking for help,
> which reminded me that I hadn't worked on it in a while) The problem
> is that I'm still stumbling over the same block that made me stop in
> the first place a number of months back. One of the function in the
> Chipmunk library (cpArbiterGetShapes) takes two double pointers to a
> cpShape. (cpShape**) So far, I have been unable to figure out how to
> make this work without a future function that accesses the cpShape
> crashing the entire Racket runtime, including the IDE window I have
> open.
>
> So the function definition for cpArbiterGetShapes is:
> static inline void cpArbiterGetShapes(const cpArbiter *arb, cpShape
> **a, cpShape **b)
>
> And my current binding in Racket is:
> (_fun _cpArbiter-pointer
>                (_ptr io _cpShape-pointer)
>                (_ptr io _cpShape-pointer)
>                -> _void)
>
> And the (pertinent) code where I use it is:
> (let*
>        ([water (cast (malloc _cpShape-pointer) _pointer _cpShape-pointer)]
>         [poly (cast (malloc _cpShape-pointer) _pointer _cpShape-pointer)]
>         [water-ptr (cast (malloc _cpShape-pointer) _pointer _cpShape-pointer)]
>         [poly-ptr (cast (malloc _cpShape-pointer) _pointer _cpShape-pointer)])
>      (memcpy water-ptr water (ctype-sizeof _cpShape-pointer))
>      (memcpy poly-ptr poly (ctype-sizeof _cpShape-pointer))
>      (cpArbiterGetShapes arb water-ptr poly-ptr)
>      (let*
>          (...
>           [count (cpPolyShapeGetNumVerts poly)] ;Note that it crashes
> on this line
>
> Which is following the buoyancy demo included in Chipmunk by default
> as close as possible. Also note that cpPolyShapeGetNumVerts is
> supposed to take a _cpShape-pointer. I'm really not sure how to do
> what I need in Racket given this situation, and all I've really seen
> in the Racket documentation is just single pointers. I've also tried
> just allocating water and poly with not water-ptr and poly-ptr and
> just using those, but that crashes Racket just the same. I would
> really, really, really appreciate any help with this. It's bugging me
> that I can't get this solved and I really want this to work.
>
> Thank you so much in advance for any assistance provided. (also I
> apologize if this ends up badly formatted. I'm not sure of formatting
> rules for a listserv when sending through email)
> ____________________
>    Racket Users list:
>    http://lists.racket-lang.org/users
>


Posted on the users mailing list.