FFI Ptr question

Derek Elkins ddarius@hotpop.com
Thu, 3 Jul 2003 03:49:21 -0400


On Thu, 3 Jul 2003 15:04:26 +0800
paul@theV.net wrote:

> On Thu, Jul 03, 2003 at 01:40:46AM -0400, Derek Elkins wrote:
> > On Thu, 3 Jul 2003 11:34:08 +0800
> > paul@theV.net wrote:
> > 
> > > If a C function returns a (void*), let's say:
> > > 
> > > data MyObj = MyObj
> > > 
> > > foreign import ccall "static myobj_ffi.h new_obj" newMyObject ::
> > > IO(Ptr MyObj)
> > > 
> > > ptr <- newMyObject
> > > 
> > > should I free the ptr afterwards or not?
> > 
> > Assuming that it should be freed even in C and nothing else is
> > managing it then I believe the answer is yes.  You can use a
> > finalizer to do it.
> 
> The wierd thing is, I cannot use the the function
> Foreign.Marshal.Alloc.free to free the ptr. I must
> use my own C function to do a simple free() call.

You didn't allocate it with the Foreign library, why would you expect to
free it with it?  Actually, I'm kind of surprised it doesn't work,
nevertheless I don't believe that the intent of the Alloc module is to
free memory allocated by a foreign language, or allocate memory that
will be freed by a foreign language.  If you need to create/destroy a
foreign value in Haskell, you typically provide both a creation and
destruction function.

> > > If I have another imported C function:
> > > 
> > > foreign import ccall "static myobj_ffi.h print_obj" printMyObject
> > > :: Ptr MyObj -> IO ()
> > > 
> > > Can I safely assume the C function print_obj(void *) always get
> > > the same pointer even if I call (printMyObject ptr) multiple
> > > times?
> > 
> > What other pointer would it pass?
> 
> The same Haskell ptr. I wonder if they'll ever change after
> creation.
> 
> My question is, if Ptr is equivalent to a raw void* pointer in 
> C, and pointers created in foreign language (which is later
> passed to Haskell as Ptr) has to be freed in the foreign
> language, then can I safely assume that Ptr isn't affected
> by Haskell's GC cycle? And what the real difference between Ptr
> and StablePtr?

The GC won't free the memory pointed at by the void * unless you attach
a finalizer, in which case you obviously shouldn't be freeing it in the
foreign code.  The Ptr you get will be freed by Haskell's GC if it
becomes unreferenced, but that won't affect what it points at. 
StablePtr's are for pointing at -Haskell- values.