FFI Ptr question
paul@theV.net
paul@theV.net
Thu, 3 Jul 2003 18:45:27 +0800
Thank you for the explanation!
So am I right to draw a picture like this?
--------- ---------
| Haskell | | Foreign |
| Ptr |----->| Data |
| Block | | Block |
--------- ---------
1. If I allocate the data block in a foreign language and returns
the pointer as Ptr through FFI, I have to free it in the
foreign language after use.
2. If I allocate the data block through Marshal.Alloc, then I
need to use Haskell free to deallocate it. (why the difference?
GHC not using the default malloc/free in C lib?)
3. If the Haskell Ptr is no longer in use, the Haskell GC will
collect it, regardless of whether it has a dangling pointer
to Foreign Data Block.
I only hope the Ptr part of FFI documentation can include some
of the malloc/free guidelines, otherwise it is quite confusing
for beginners.
Regards,
.paul.
On Thu, Jul 03, 2003 at 03:49:21AM -0400, Derek Elkins wrote:
> 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.
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe