FFI Ptr question
Sven Panne
Sven.Panne@informatik.uni-muenchen.de
Thu, 03 Jul 2003 13:42:19 +0200
paul@theV.net wrote:
> So am I right to draw a picture like this? [...]
Basically, yes. Or from the Haskell implementation's view:
"I don't have a clue what a Ptr really is, but it fits in C's void*."
> [ 1. & 2. ]
The requirement for matching allocators and deallocators is not much
different from the situation in e.g. C++: You can't "free" an object
constructed via "new", you can't simply "delete" an array allocated
with "new[]", etc.
> 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.
It is by no means clear if the pointer is "dangling", even if Haskell
knew that a Ptr is really a pointer. Other C pointers or Haskell Ptrs
could still reference the data.
What the best approach is, depends on your problem:
a) The C part does more than a simple malloc/free in its
(de-)allocation functions, but the lifetime of the object is
restricted. In this case, a "withNewFoo" Haskell action is often a
good approach, e.g.:
withNewFoo :: (Ptr a -> IO b) -> IO b
withNewFoo = bracket c_alloc c_dealloc
foreign import ccall unsafe "c_alloc" c_alloc :: IO (Ptr a)
foreign import ccall unsafe "c_dealloc" c_dealloc :: Ptr a -> IO ()
b) Same as a), but the lifetime of the C object should be under
control of the Haskell GC. In this case, you can use a ForeignPtr,
which is basically a Ptr with attached finalizers.
c) If the C part simply needs a buffer for some time, there are quite
a few possibilities, depending on the required lifetime and
ownership of the buffer:
* explicit control via Foreign.Marshal.Alloc.malloc and
Foreign.Marshal.Alloc.free
* pooled allocation ("all or nothing") via Foreign.Marshal.Pool
* Foreign.ForeignPtr.mallocForeignPtr* puts the buffer under
control of Haskell's GC
* explicitly delimited lifetime via Foreign.Marshal.Alloc.alloca
> I only hope the Ptr part of FFI documentation can include some of
> the malloc/free guidelines, otherwise it is quite confusing for
> beginners.
The FFI spec is, well, a spec and not intended as a tutorial, but
Alastair has written a guide to the FFI:
http://www.reid-consulting-uk.ltd.uk/docs/ffi.html
Cheers,
S.