Go to the first, previous, next, last section, table of contents.
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.