4.10. ForeignObj

This module is part of the Foreign Function Interface (FFI) and will usually be imported via the module Foreign (see Section 4.9). The type ForeignObj represents references to objects that are maintained in a foreign language, i.e., that are not part of the data structures usually managed by the Haskell storage manager. The essential difference between ForeignObjs and vanilla memory references of type Addr (Section 4.1) is that the former may be associated with finalisers. A finaliser is a routine that is invoked when the Haskell storage manager detects that - within the Haskell heap and stack - there are no more references left that are pointing to the ForeignObj. Typically, the finaliser will, then, invoke routines in the foreign language that free the resources bound by the foreign object.

4.10.1. The Standard Interface

data ForeignObj		-- abstract handle to foreign object
instance Eq ForeignObj

newForeignObj       :: Addr       -> IO () -> IO ForeignObj
addForeignFinalizer :: ForeignObj -> IO () -> IO () 
foreignObjToAddr    :: ForeignObj -> Addr  -- *unsafe* operation

The behaviour of the functions is as follows:

newForeignObj :: Addr -> IO () -> IO ForeignObj

Turns a plain memory reference into a foreign object by associating a finaliser - given by the monadic operation - with the reference. The finaliser will be executed after the last reference to the foreign object is dropped. Note that there is no guarantee on how soon the finaliser is executed after the last reference was dropped; this depends on the details of the Haskell storage manager. The only guarantee is that the finaliser runs before the program terminates.

addForeignFinalizer :: ForeignObj -> IO () -> IO ()

This function adds another finaliser to the given foreign object. No guarantees are made on the order in which multiple finalisers for a single object are run.

foreignObjToAddr :: ForeignObj -> Addr

Extract the plain memory reference contained in a foreign object.

This routine should be handled with a lot of care: The reference to the foreign object that is passed in a call to foreignObjToAddr may be the last reference to the object that exists in Haskell land. In this case, the finalisers of the foreign object may be activated any time after the call to foreignObjToAddr is evaluated. If the finalisers, for example, trigger deallocation of the foreign object's memory area, the Addr obtained by the call to foreignObjToAddr may be rendered invalid when garbage collection hits after the call. Whether this is a problem or not depends on the details of the finaliser code and the operations subsequently performed on the Addr.

If it must be guaranteed that the finalisers are not yet run, a stable pointer (Section 4.24) should be used to establish a guaranteed reference to the foreign object. The finalisers will, then, certainly not be run before StablePtr.freeStablePtr is used.

4.10.2. The Standard C-side Interface

The following definition is available to C programs inter-operating with Haskell code when including the header HsFFI.h.

typedef void* HsForeignObj;  /* C representation of a ForeignObj */

4.10.3. Deprecated Functions

The following functions are deprecated in the new FFI. Do not use the following functions if you are interested in portability. Instead of the indexXXX, readXXX, and writeXXX functions, use the module Storable (Section 4.25).

Most of these functions are here for legacy reasons and may just vanish one day. You have been warned.

writeForeignObj :: ForeignObj -> Addr{-new value-} -> IO ()
makeForeignObj :: Addr -> Addr -> IO ForeignObj

indexCharOffForeignObj   :: ForeignObj -> Int -> Char
indexIntOffForeignObj    :: ForeignObj -> Int -> Int
indexWordOffForeignObj   :: ForeignObj -> Int -> Word
indexAddrOffForeignObj   :: ForeignObj -> Int -> Addr
indexFloatOffForeignObj  :: ForeignObj -> Int -> Float
indexDoubleOffForeignObj :: ForeignObj -> Int -> Double
indexWord8OffForeignObj  :: ForeignObj -> Int -> Word8
indexWord16OffForeignObj :: ForeignObj -> Int -> Word16
indexWord32OffForeignObj :: ForeignObj -> Int -> Word32
indexWord64OffForeignObj :: ForeignObj -> Int -> Word64

indexInt8OffForeignObj  :: ForeignObj -> Int -> Int8
indexInt16OffForeignObj :: ForeignObj -> Int -> Int16
indexInt32OffForeignObj :: ForeignObj -> Int -> Int32
indexInt64OffForeignObj :: ForeignObj -> Int -> Int64

-- read value out of mutable memory
readCharOffForeignObj    :: ForeignObj -> Int -> IO Char
readIntOffForeignObj     :: ForeignObj -> Int -> IO Int
readWordOffForeignObj    :: ForeignObj -> Int -> IO Word
readAddrOffForeignObj    :: ForeignObj -> Int -> IO Addr
readFloatOffForeignObj   :: ForeignObj -> Int -> IO Float
readDoubleOffForeignObj  :: ForeignObj -> Int -> IO Double
readWord8OffForeignObj   :: ForeignObj -> Int -> IO Word8
readWord16OffForeignObj  :: ForeignObj -> Int -> IO Word16
readWord32OffForeignObj  :: ForeignObj -> Int -> IO Word32
readWord64OffForeignObj  :: ForeignObj -> Int -> IO Word64
readInt8OffForeignObj    :: ForeignObj -> Int -> IO Int8
readInt16OffForeignObj   :: ForeignObj -> Int -> IO Int16
readInt32OffForeignObj   :: ForeignObj -> Int -> IO Int32
readInt64OffForeignObj   :: ForeignObj -> Int -> IO Int64

writeCharOffForeignObj   :: ForeignObj -> Int -> Char   -> IO ()
writeIntOffForeignObj    :: ForeignObj -> Int -> Int    -> IO ()
writeWordOffForeignObj   :: ForeignObj -> Int -> Word   -> IO ()
writeAddrOffForeignObj   :: ForeignObj -> Int -> Addr   -> IO ()
writeFloatOffForeignObj  :: ForeignObj -> Int -> Float  -> IO ()
writeDoubleOffForeignObj :: ForeignObj -> Int -> Double -> IO ()
writeWord8OffForeignObj  :: ForeignObj -> Int -> Word8  -> IO ()
writeWord16OffForeignObj :: ForeignObj -> Int -> Word16 -> IO ()
writeWord32OffForeignObj :: ForeignObj -> Int -> Word32 -> IO ()
writeWord64OffForeignObj :: ForeignObj -> Int -> Word64 -> IO ()
writeInt8OffForeignObj   :: ForeignObj -> Int -> Int8   -> IO ()
writeInt16OffForeignObj  :: ForeignObj -> Int -> Int16  -> IO ()
writeInt32OffForeignObj  :: ForeignObj -> Int -> Int32  -> IO ()
writeInt64OffForeignObj  :: ForeignObj -> Int -> Int64  -> IO ()