[racket] FFI: Casting pointers

From: Michael W (mwilber at uccs.edu)
Date: Sun Jan 22 19:26:39 EST 2012

HMM! Interesting.

This function is ov_fopen, which expects a fresh blank
OggVorbis_File struct, and it populates that struct's fields.

This signature comes close to working but eventually segfaults,
likely because the result struct isn't allocated with 'interior.
Perhaps something in libvorbisfile still keeps references to it?

(_fun [path : _path]
      [vf : (_ptr o _OggVorbis_File)]
      -> [return : _int]
      -> (if (zero? return) vf #f))

I'll remember this for other libraries though. Thanks for the
tip!

One hour ago, Jon Rafkind wrote:
> Actually can't you just use an input specification for the pointer?
> 
> (_ fun [vf : (_ptr i _OggVorbis_File)])
> 
> As long as you can define the OggVorbis_File struct with the ffi.
> 
> If not your solution is probably fine.
> 
> On 01/22/2012 03:59 PM, Michael W wrote:
> > Wow, thanks!
> >
> > After a bit of reading, I arrived at this, which seems to work:
> >
> > (_fun ...
> >       [vf : _OggVorbis_File-pointer
> >           = (let ([file (malloc _OggVorbis_File 'interior)])
> >                (set-cpointer-tag! file OggVorbis_File-tag)
> >                file)]
> >       ...)
> >
> > 42 minutes ago, Jon Rafkind wrote:
> >> I'm pretty sure you can use cpointer-push-tag!
> >>
> >> http://docs.racket-lang.org/foreign/foreign_tagged-pointers.html?q=cpointer-push&q=in-lines&q=read-bytes&q=command&q=for/fold#(def._((lib._ffi/unsafe..rkt)._cpointer-push-tag!))
> >>
> >> (let ([file (malloc)])
> >>   (cpointer-push-tag! file _OggVorbis-file-pointer
> >>   file)
> >>
> >> On 01/22/2012 02:14 PM, Michael W wrote:
> >>> Hello!
> >>>
> >>> In the FFI library, is there a way to cast one pointer type
> >>> straight to another? I'm working with libvorbisfile (PLaneT
> >>> package forthcoming) which expects me to allocate my own
> >>> OggVorbis_File cstruct and pass that everywhere.
> >>>
> >>> I ask because (malloc _OggVorbis_File) returns a _pointer, not an
> >>> _OggVorbis_File-pointer, and _fun and friends don't accept either
> >>> type in place of the other.
> >>>
> >>> If I say:
> >>>
> >>>    (cast
> >>>     (malloc _OggVorbis_File)
> >>>     _pointer _OggVorbis_File-pointer)
> >>>
> >>> ...That's bad -- because I never keep the original pointer
> >>> returned by the (malloc) call, the garbage collector reclaims
> >>> that memory even though the _OggVorbis_File-pointer still points
> >>> to it.
> >>>
> >>> My current workaround is to just use (malloc _OggVorbis_File)
> >>> everywhere and have _pointer types in my (_fun ...) declarations.
> >>> Is this the preferred way of doing it?
> >>>
> >>> Is there a way to ask (malloc) to return a different pointer type
> >>> than _pointer?
> >>>
> >>> Thanks for your help.
> >>>
> 

-- 
Take care,
    _mike

Posted on the users mailing list.