Go to the first, previous, next, last section, table of contents.

Foreign objects

This module provides the `ForeignObj' type and wrappers around the primitive operations on foreign objects.
data ForeignObj = ForeignObj ForeignObj#

makeForeignObj 
        :: Addr   -- object to be boxed up as a ForeignObj
        -> Addr   -- finaliser 
        -> IO ForeignObj

writeForeignObj 
        :: ForeignObj   -- previously created foreign object
        -> Addr         -- new value
        -> IO ()

A typical use of `ForeignObj' is in constructing Haskell bindings to external libraries. A good example is that of writing a binding to an image-processing library (which was actually the main motivation for implementing `ForeignObj''s precursor, `MallocPtr#'). The images manipulated are not stored in the Haskell heap, either because the library insist on allocating them internally or we (sensibly) decide to spare the GC from having to heave heavy images around.
data Image = Image ForeignObj
The `ForeignObj' type is then used to refer to the externally allocated image, and to acheive some type safety, the Haskell binding defines the `Image' data type. So, a value of type `ForeignObj' is used to "box" up an external reference into a Haskell heap object that we can then indirectly reference:
createImage :: (Int,Int) -> IO Image
So far, this looks just like an `Addr' type, but `ForeignObj' offers a bit more, namely that we can specify a finalisation routine to invoke when the `ForeignObj' is discarded by the GC. The garbage collector invokes the finalisation routine associated with the `ForeignObj', saying " Thanks, I'm through with this now.." For the image-processing library, the finalisation routine could for the images free up memory allocated for them. The finalisation routine has currently to be written in C (the finalisation routine can in turn call on `FreeStablePtr' to deallocate a stable pointer). Associating a finalisation routine with an external object is done by calling `makeForeignObj'. Note: the foreign object value and its finaliser are contained in the `ForeignObj', so there's no danger of an aggressive optimiser somehow separating the two (with the result that the foreign reference would not be freed). (Implementation: a linked list of all `ForeignObj#'s is maintained to allow the garbage collector to detect when a `ForeignObj#' becomes garbage.) Like `Array', `ForeignObj#'s are represented by heap objects. Upon controlled termination of the Haskell program, all `ForeignObjs' are freed, invoking their respective finalisers before terminating.
Go to the first, previous, next, last section, table of contents.