5 Marshalling
In addition to the language extension discussed in previous sections, the FFI includes a set of standard
libraries, which ease portable use of foreign functions as well as marshalling of compound structures.
Generally, the marshalling of Haskell structures into a foreign representation and vice versa can be
implemented in either Haskell or the foreign language. At least where the foreign language is
at a significantly lower level, e.g. C, there are good reasons for doing the marshalling in
Haskell:
- Haskell’s lazy evaluation strategy would require any foreign code that attempts to access
Haskell structures to force the evaluation of these structures before accessing them. This
would lead to complicated code in the foreign language, but does not need any extra
consideration when coding the marshalling in Haskell.
- Despite the fact that marshalling code in Haskell tends to look like C in Haskell syntax, the
strong type system still catches many errors that would otherwise lead to difficult-to-debug
runtime faults.
- Direct access to Haskell heap structures from a language like C--especially, when marshalling
from C to Haskell, i.e., when Haskell structures are created--carries the risk of corrupting
the heap, which usually leads to faults that are very hard to debug.
Consequently, the Haskell FFI emphasises Haskell-side marshalling.
The interface to the marshalling libraries is provided by the module Foreign plus a
language-dependent module per supported language. In particular, the standard requires the availability
of the module CForeign, which simplifies portable interfacing with external C code. Language-dependent
modules, such as CForeign, generally provide Haskell types representing the basic types of the foreign
language using a representation that is compatible with the foreign types as implemented by the
default implementation of the foreign language on the present architecture. This is especially
important for languages where the standard leaves some aspects of the implementation of basic
types open. For example, in C, the size of the various integral types is not fixed. Thus, to
represent C interfaces faithfully in Haskell, for each integral type in C, we need to have an
integral type in Haskell that is guaranteed to have the same size as the corresponding C
type.
In the following, the interface of the language independent support is defined. The interface for
C-specific support is discussed in Section 6.
5.1 Foreign
The module Foreign combines the interfaces of all modules providing language-independent marshalling
support. These modules are Bits, Int, Word, Ptr, ForeignPtr, StablePtr, Storable, MarshalAlloc,
MarshalArray, MarshalError, and MarshalUtils.
Sometimes an external entity is a pure function, except that it passes arguments and/or results via
pointers. To permit the packaging of such entities as pure functions, Foreign provides the following
primitive:
-
unsafePerformIO :: IO a -> a
- Return the value resulting from executing the IO action. This value should be independent
of the environment; otherwise, the system behaviour is undefined.
If the IO computation wrapped in unsafePerformIO performs side effects, then the relative
order in which those side effects take place (relative to the main IO trunk, or other calls
to unsafePerformIO) is indeterminate. Moreover, the side effects may be performed several
times or not at all, depending on lazy evaluation and whether the compiler unfolds an
enclosing definition.
Great care should be exercised in the use of this primitive. Not only because of the danger of
introducing side effects, but also because unsafePerformIO may compromise typing; to avoid
this, the programmer should ensure that the result of unsafePerformIO has a monomorphic
type.
5.2 Bits
This module provides functions implementing typical bit operations overloaded for the standard integral
types Int and Integer as well as the types provided by the modules Int and Word in Section 5.3. The
overloading is implemented via a new type class Bits, which is a subclass of Num and has the following
member functions:
-
(.&.), (.|.), xor :: Bits a => a -> a -> a
- Implement bitwise conjunction, disjunction, and exclusive or. The infix operators have the
following precedences:
infixl 7 .&.
infixl 6 `xor`
infixl 5 .|.
|
-
complement :: Bits a => a -> a
- Calculate the bitwise complement of the argument.
-
shift, rotate :: Bits a => a -> Int -> a
- Shift or rotate the bit pattern to the left for a positive second argument and to the right for a
negative argument. The function shift performs sign extension on signed number types; i.e., right
shifts fill the top bits with 1 if the number is negative and with 0 otherwise. These operators have
the following precedences as infix operators:
infixl 8 `shift`, `rotate`
|
For unbounded types (e.g., Integer), rotate is equivalent to shift. An instance can define either
this unified rotate or rotateL and rotateR, depending on which is more convenient for the type
in question.
-
bit :: Bits a => Int -> a
- Obtain a value where only the nth bit is set.
-
setBit, clearBit, complementBit :: a -> Int -> a
- Set, clear, or complement the bit at the given position.
-
testBit :: Bits a => a -> Int -> Bool
- Check whether the nth bit of the first argument is set.
-
bitSize :: Bits a => a -> Int
-
-
isSigned :: Bits a => a -> Bool
- Respectively, query the number of bits of values of type a and whether these values are signed.These functions never evaluate their argument. The function bitSize is undefined for unbounded
types (e.g., Integer).
-
shiftL, shiftR :: Bits a => a -> Int -> a
-
-
rotateL, rotateR :: Bits a => a -> Int -> a
- The functions shiftR and rotateR are synonyms for shift and rotate; shiftL and rotateLnegate the second argument. These operators have the following precedences as infix
operators:
infixl 8 `shiftL`, `shiftR`, `rotateL`, `rotateR`
|
Bits are numbered from 0 with bit 0 being the least significant bit. A minimal complete definition of the
type class Bits must include definitions for the following functions: (.&.), (.|.), xor, complement,
shift, rotate, bitSize, and isSigned.
5.3 Int and Word
The two modules Int and Word provide the following signed and unsigned integral types of fixed
size:
|
|
|
| Size in bits | Signed | Unsigned |
|
|
|
|
|
|
| 8 | Int8 | Word8 |
| 16 | Int16 | Word16 |
| 32 | Int32 | Word32 |
| 64 | Int64 | Word64 |
|
|
|
| |
For these integral types, the modules Int and Word export class instances for the class Bits and all type
classes for which Int has an instance in the Haskell 98 Prelude and standard libraries. The constraints on
the implementation of these instances are also the same as those outlined for Int in the Haskell Report.
There is, however, the additional constraint that all arithmetic on the fixed-sized types is performed
modulo 2n.
5.4 Ptr
The module Ptr provides typed pointers to foreign entities. We distinguish two kinds of
pointers: pointers to data and pointers to functions. It is understood that these two kinds of
pointers may be represented differently as they may be references to data and text segments,
respectively.
5.4.1 Data Pointers
The interface defining data pointers and associated operations is as follows:
-
data Ptr a
- A value of type Ptr a represents a pointer to an object, or an array of objects, which may
be marshalled to or from Haskell values of type a. The type a will normally be an instance
of class Storable (see Section 5.7), which provides the necessary marshalling operations.
Instances for the classes Eq, Ord, and Show are provided.
-
nullPtr :: Ptr a
- The constant nullPtr contains a distinguished value of Ptr that is not associated with a
valid memory location.
-
castPtr :: Ptr a -> Ptr b
- The castPtr function casts a pointer from one type to another.
-
plusPtr :: Ptr a -> Int -> Ptr b
- Advances the given address by the given offset in bytes.
-
alignPtr :: Ptr a -> Int -> Ptr a
- Given an arbitrary address and an alignment constraint, alignPtr yields an address, the
same or next higher, that fulfills the alignment constraint. An alignment constraint x is
fulfilled by any address divisible by x. This operation is idempotent.
-
minusPtr :: Ptr a -> Ptr b -> Int
- Compute the offset required to get from the first to the second argument. We have
p2 == p1 `plusPtr` (p2 `minusPtr` p1)
|
It should be noted that the use of Int for pointer differences essentially forces any implementation to
represent Int in as many bits as used in the representation of pointer values.
5.4.2 Function Pointers
The interface defining function pointers and associated operations is as follows:
-
data FunPtr a
- A value of type FunPtr a is a pointer to a piece of code. It may be the pointer to a C function
or to a Haskell function created using a wrapper stub as outlined in Section 4.1. For
example,
type Compare = Int -> Int -> Bool
foreign import ccall "wrapper"
mkCompare :: Compare -> IO (FunPtr Compare)
|
Instances for the classes Eq, Ord, and Show are provided.
-
nullFunPtr :: FunPtr a
- The constant nullFunPtr contains a distinguished value of FunPtr that is not associated with a
valid memory location.
-
castFunPtr :: FunPtr a -> FunPtr b
- Cast a FunPtr to a FunPtr of a different type.
-
freeHaskellFunPtr :: FunPtr a -> IO ()
- Release the storage associated with the given FunPtr, which must have been obtained from a
wrapper stub. This should be called whenever the return value from a foreign import wrapper
function is no longer required; otherwise, the storage it uses will leak.
Moreover, there are two functions that are only valid on architectures where data and function
pointers range over the same set of addresses. Only where bindings to external libraries are made whose
interface already relies on this assumption, should the use of castFunPtrToPtr and castPtrToFunPtr be
considered; otherwise, it is recommended to avoid using these functions.
-
castFunPtrToPtr :: FunPtr a -> Ptr b
-
-
castPtrToFunPtr :: Ptr a -> FunPtr b
- These two functions cast Ptrs to FunPtrs and vice versa.
5.5 ForeignPtr
The type ForeignPtr represents references to objects that are maintained in a foreign language, i.e.,
objects that are not part of the data structures usually managed by the Haskell storage manager. The
type ForeignPtr is parameterised in the same way as Ptr (cf. Section 5.4), but in contrast to vanilla
memory references of type Ptr, ForeignPtrs may be associated with finalizers. A finalizer 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 ForeignPtr. Typically, the finalizer will
free the resources bound by the foreign object. Finalizers are generally implemented in the foreign
language
and have either of the following two Haskell types:
type FinalizerPtr a = FunPtr ( Ptr a -> IO ())
type FinalizerEnvPtr env a = FunPtr (Ptr env -> Ptr a -> IO ())
|
A foreign finalizer is represented as a pointer to a C function of type Ptr a -> IO () or a C function of
type Ptr env -> Ptr a -> IO (), where Ptr env represents an optional environment passed to the
finalizer on invocation. That is, a foreign finalizer attached to a finalized pointer ForeignPtr a gets the
finalized pointer in the form of a raw pointer of type Ptr a as an argument when it is invoked. In
addition, a foreign finalizer of type FinalizerEnvPtr env a also gets an environment pointer of type
Ptr env. There is no guarantee on how soon the finalizer is executed after the last reference to the
associated foreign pointer was dropped; this depends on the details of the Haskell storage manager. The
only guarantee is that the finalizer runs before the program terminates. Whether a finalizer may
call back into the Haskell system is system dependent. Portable code may not rely on such
callbacks.
Foreign finalizers that expect an environment are a means to model closures in languages that do not
support them natively, such as C. They recover part of the convenience lost by requiring finalizers to be
defined in the foreign languages rather than in Haskell.
The data type ForeignPtr and associated operations have the following signature and
purpose:
-
data ForeignPtr a
- A value of type ForeignPtr a represents a pointer to an object, or an array of objects,
which may be marshalled to or from Haskell values of type a. The type a will normally be
an instance of class Storable (see Section 5.7), which provides the marshalling operations.
Instances for the classes Eq, Ord, and Show are provided. Equality and ordering of two foreign
pointers are the same as for the plain pointers obtained with unsafeForeignPtrToPtr from
those foreign pointers.
-
newForeignPtr_ :: Ptr a -> IO (ForeignPtr a)
- Turn a plain memory reference into a foreign pointer that may be associated with finalizers
by using addForeignPtrFinalizer.
-
newForeignPtr :: FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
- This is a convenience function that turns a plain memory reference into a foreign pointer and
immediately adds a finalizer. It is defined as
newForeignPtr finalizer ptr =
do
fp <- newForeignPtr_ ptr
addForeignPtrFinalizer finalizer fp
return fp
|
-
newForeignPtrEnv :: FinalizerEnvPtr env a -> Ptr env -> Ptr a -> IO (ForeignPtr a)
- This variant of newForeignPtr adds a finalizer that expects an environment in addition to the
finalized pointer. The environment that will be passed to the finalizer is fixed by the second
argument to newForeignPtrEnv.
-
addForeignPtrFinalizer :: FinalizerPtr a -> ForeignPtr a -> IO ()
- Add a finalizer to the given foreign pointer. All finalizers associated with a single foreign pointer
are executed in the opposite order of their addition--i.e., the finalizer added last will be executed
first.
-
addForeignPtrFinalizerEnv :: FinalizerEnvPtr env a -> Ptr env -> ForeignPtr a
-
-
-> IO ()
- Add a finalizer that expects an environment to an existing foreign pointer.
-
mallocForeignPtr :: Storable a => IO (ForeignPtr a)
- Allocate a block of memory that is sufficient to hold values of type a. The size of
the memory area is determined by the function Storable.sizeOf (Section 5.7). This
corresponds to MarshalAlloc.malloc (Section 5.8), but automatically attaches a finalizer
that frees the block of memory as soon as all references to that block of of memory
have been dropped. It is not guaranteed that the block of memory was allocated by
MarshalAlloc.malloc; so, MarshalAlloc.realloc must not be applied to the resulting
pointer.
-
mallocForeignPtrBytes :: Int -> IO (ForeignPtr a)
- Allocate a block of memory of the given number of bytes with a finalizer attached that frees the
block of memory as soon as all references to that block of memory have been dropped. As
for mallocForeignPtr, MarshalAlloc.realloc must not be applied to the resulting
pointer.
-
mallocForeignPtrArray :: Storable a => Int -> IO (ForeignPtr a)
-
-
mallocForeignPtrArray0 :: Storable a => Int -> IO (ForeignPtr a)
- These functions correspond to MarshalArray’s mallocArray and mallocArray0, respectively, butyield a memory area that has a finalizer attached that releases the memory area. As with the
previous two functions, it is not guaranteed that the block of memory was allocated by
MarshalAlloc.malloc.
-
withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
- This is a way to obtain the pointer living inside a foreign pointer. This function takes a function
which is applied to that pointer. The resulting IO action is then executed. The foreign
pointer is kept alive at least during the whole action, even if it is not used directly
inside. Note that it is not safe to return the pointer from the action and use it after
the action completes. All uses of the pointer should be inside the withForeignPtr
bracket.
More precisely, the foreign pointer may be finalized after withForeignPtr is finished
if the first argument was the last occurrence of that foreign pointer. Finalisation of
the foreign pointer might render the pointer that is passed to the function useless.
Consequently, this pointer cannot be used safely anymore after the withForeignPtr is finished,
unless the function touchForeignPtr is used to explicitly keep the foreign pointer
alive.
This function is normally used for marshalling data to or from the object pointed to by the
ForeignPtr, using the operations from the Storable class.
-
unsafeForeignPtrToPtr :: ForeignPtr a -> Ptr a
- Extract the pointer component of a foreign pointer. This is a potentially dangerous operation. If
the argument to unsafeForeignPtrToPtr is the last usage occurrence of the given foreign pointer,
then its finalizer(s) will be run, which potentially invalidates the plain pointer just obtained. Hence,
touchForeignPtr must be used wherever it has to be guaranteed that the pointer lives on--i.e.,
has another usage occurrence.
It should be noticed that this function does not need to be monadic when used in combination
with touchForeignPtr. Until the unsafeForeignPtrToPtr is executed, the thunk representing the
suspended call keeps the foreign pointer alive. Afterwards, the touchForeignPtr keeps the pointer
alive.
To avoid subtle coding errors, hand written marshalling code should preferably use the
function withForeignPtr rather than unsafeForeignPtrToPtr and touchForeignPtr.
However, the later routines are occasionally preferred in tool-generated marshalling
code.
-
touchForeignPtr :: ForeignPtr a -> IO ()
- Ensure that the foreign pointer in question is alive at the given place in the sequence of IO
actions. In particular, withForeignPtr does a touchForeignPtr after it executes the user
action.
This function can be used to express liveness dependencies between ForeignPtrs: For example, if
the finalizer for one ForeignPtr touches a second ForeignPtr, then it is ensured that the second
ForeignPtr will stay alive at least as long as the first. This can be useful when you want to
manipulate interior pointers to a foreign structure: You can use touchForeignPtr to express the
requirement that the exterior pointer must not be finalized until the interior pointer is no longer
referenced.
-
castForeignPtr :: ForeignPtr a -> ForeignPtr b
- Cast a ForeignPtr parameterised by one type into another type.
5.6 StablePtr
A stable pointer is a reference to a Haskell expression that is guaranteed not to be affected by garbage
collection, i.e., it will neither be deallocated nor will the value of the stable pointer itself change during
garbage collection (ordinary references may be relocated during garbage collection). Consequently, stable
pointers can be passed to foreign code, which can treat it as an opaque reference to a Haskell
value.
The data type and associated operations have the following signature and purpose:
-
data StablePtr a
- Values of this type represent a stable reference to a Haskell value of type a.
-
newStablePtr :: a -> IO (StablePtr a)
- Create a stable pointer referring to the given Haskell value.
-
deRefStablePtr :: StablePtr a -> IO a
- Obtain the Haskell value referenced by a stable pointer, i.e., the same value that was passed
to the corresponding call to makeStablePtr. If the argument to deRefStablePtr has already
been freed using freeStablePtr, the behaviour of deRefStablePtr is undefined.
-
freeStablePtr :: StablePtr a -> IO ()
- Dissolve the association between the stable pointer and the Haskell value. Afterwards, if the
stable pointer is passed to deRefStablePtr or freeStablePtr, the behaviour is undefined.
However, the stable pointer may still be passed to castStablePtrToPtr, but the Ptr ()
value returned by castStablePtrToPtr, in this case, is undefined (in particular, it may be
Ptr.nullPtr). Nevertheless, the call to castStablePtrToPtr is guaranteed not to diverge.
-
castStablePtrToPtr :: StablePtr a -> Ptr ()
- Coerce a stable pointer to an address. No guarantees are made about the resulting
value, except that the original stable pointer can be recovered by castPtrToStablePtr. In
particular, the address may not refer to an accessible memory location and any attempt
to pass it to the member functions of the class Storable (Section 5.7) leads to undefined
behaviour.
-
castPtrToStablePtr :: Ptr () -> StablePtr a
- The inverse of castStablePtrToPtr, i.e., we have the identity
sp == castPtrToStablePtr (castStablePtrToPtr sp)
|
for any stable pointer sp on which freeStablePtr has not been executed yet. Moreover,
castPtrToStablePtr may only be applied to pointers that have been produced by
castStablePtrToPtr.
It is important to free stable pointers that are no longer required by using freeStablePtr.
Otherwise, the object referenced by the stable pointer will be retained in the heap.
5.7 Storable
To code marshalling in Haskell, Haskell data structures need to be translated into the binary
representation of a corresponding data structure of the foreign language and vice versa. To this
end, the module Storable provides routines that manipulate primitive data types stored in
unstructured memory blocks. The class Storable is instantiated for all primitive types that can be
stored in raw memory. Reading and writing these types to arbitrary memory locations is
implemented by the member functions of the class. The member functions, furthermore,
encompass support for computing the storage requirements and alignment restrictions of storable
types.
Memory addresses are represented as values of type Ptr a (Section 5.4), where a is a storable type.
The type argument to Ptr provides some type safety in marshalling code, as pointers to
different types cannot be mixed without an explicit cast. Moreover, it assists in resolving
overloading.
The class Storable is instantiated for all standard basic types of Haskell, the fixed size integral
types of the modules Int and Word (Section 5.3), data and function pointers (Section 5.4), and stable
pointers (Section 5.6). There is no instance of Storable for foreign pointers. The intention is to ensure
that storing a foreign pointer requires an explicit cast to a plain Ptr, which makes it obvious that the
finalizers of the foreign pointer may be invoked at this point if no other reference to the pointer exists
anymore.
The signatures and behaviour of the member functions of the class Storable are as
follows:
-
sizeOf :: Storable a => a -> Int
-
-
alignment :: Storable a => a -> Int
- The function sizeOf computes the storage requirements (in bytes) of the argument, andalignment computes the alignment constraint of the argument. An alignment constraint x is
fulfilled by any address divisible by x. Both functions do not evaluate their argument, but
compute the result on the basis of the type of the argument alone. We require that the size
is divisible by the alignment. (Thus each element of a contiguous array of storable values
will be properly aligned if the first one is.)
-
peekElemOff :: Storable a => Ptr a -> Int -> IO a
- Read a value from a memory area regarded as an array of values of the same kind. The first
argument specifies the start address of the array and the second the index into the array
(the first element of the array has index 0).
-
pokeElemOff :: Storable a => Ptr a -> Int -> a -> IO ()
- Write a value to a memory area regarded as an array of values of the same kind. The first
and second argument are as for peekElemOff.
-
peekByteOff :: Storable a => Ptr b -> Int -> IO a
- Read a value from a memory location given by a base address and byte offset from that
base address.
-
pokeByteOff :: Storable a => Ptr b -> Int -> a -> IO ()
- Write a value to a memory location given by a base address and offset from that base
address.
-
peek :: Storable a => Ptr a -> IO a
- Read a value from the given memory location.
-
poke :: Storable a => Ptr a -> a -> IO ()
- Write the given value to the given memory location.
On some architectures, the peek and poke functions might require properly aligned addresses to function
correctly. Thus, portable code should ensure that when peeking or poking values of some type a, the
alignment constraint for a, as given by the function alignment is fulfilled.
A minimal complete definition of Storable needs to define sizeOf, alignment, one of peek,
peekElemOff, or peekByteOff, and one of poke, pokeElemOff, and pokeByteOff.
5.8 MarshalAlloc
The module MarshalAlloc provides operations to allocate and deallocate blocks of raw memory (i.e.,
unstructured chunks of memory outside of the area maintained by the Haskell storage manager). These
memory blocks are commonly used to pass compound data structures to foreign functions or to provide
space in which compound result values are obtained from foreign functions. For example, Haskell lists are
typically passed as C arrays to C functions; the storage space for such an array can be allocated by the
following functions:
-
malloc :: Storable a => IO (Ptr a)
- Allocate a block of memory that is sufficient to hold values of type a. The size of the memory
area is determined by the function Storable.sizeOf (Section 5.7).
-
mallocBytes :: Int -> IO (Ptr a)
- Allocate a block of memory of the given number of bytes. The block of memory is sufficiently
aligned for any of the basic foreign types (see Section 3.2) that fits into a memory block of
the allocated size.
-
alloca :: Storable a => (Ptr a -> IO b) -> IO b
- Allocate a block of memory of the same size as malloc, but the reference is passed to a
computation instead of being returned. When the computation terminates, free the memory
area again. The operation is exception-safe; i.e., allocated memory is freed if an exception is
thrown in the marshalling computation.
-
allocaBytes :: Int -> (Ptr a -> IO b) -> IO b
- As alloca, but allocate a memory area of the given size. The same alignment constraint as
for mallocBytes holds.
-
realloc :: Storable b => Ptr a -> IO (Ptr b)
- Resize a memory area that was allocated with malloc or mallocBytes to the size needed
to store values of type b. The returned pointer may refer to an entirely different memory
area, but will be suitably aligned to hold values of type b. The contents of the referenced
memory area will be the same as of the original pointer up to the minimum of the size of
values of type a and b. If the argument to realloc is Ptr.nullPtr, realloc behaves like
malloc.
-
reallocBytes :: Ptr a -> Int -> IO (Ptr a)
- As realloc, but allocate a memory area of the given size. In addition, if the requested size
is 0, reallocBytes behaves like free.
-
free :: Ptr a -> IO ()
- Free a block of memory that was allocated with malloc, mallocBytes, realloc,
reallocBytes, or any of the allocation functions from MarshalArray (see Section 5.9).
-
finalizerFree :: FinalizerPtr a
- Foreign finalizer that performs the same operation as free.
If any of the allocation functions fails, a value of Ptr.nullPtr is produced. If free or reallocBytes is
applied to a memory area that has been allocated with alloca or allocaBytes, the behaviour is
undefined. Any further access to memory areas allocated with alloca or allocaBytes, after the
computation that was passed to the allocation function has terminated, leads to undefined behaviour.
Any further access to the memory area referenced by a pointer passed to realloc, reallocBytes, or
free entails undefined behaviour.
5.9 MarshalArray
The module MarshalArray provides operations for marshalling Haskell lists into monolithic arrays and
vice versa. Most functions come in two flavours: one for arrays terminated by a special termination
element and one where an explicit length parameter is used to determine the extent of an
array. The typical example for the former case are C’s NUL terminated strings. However,
please note that C strings should usually be marshalled using the functions provided by
CString (Section 6.3) as the Unicode encoding has to be taken into account. All functions
specifically operating on arrays that are terminated by a special termination element have a
name ending on 0--e.g., mallocArray allocates space for an array of the given size, whereas
mallocArray0 allocates space for one more element to ensure that there is room for the
terminator.
The following functions are provided by the module:
-
mallocArray :: Storable a => Int -> IO (Ptr a)
-
-
allocaArray :: Storable a => Int -> (Ptr a -> IO b) -> IO b
-
reallocArray :: Storable a => Ptr a -> Int -> IO (Ptr a)
- The functions behave like the functions malloc, alloca, and realloc provided by themodule MarshalAlloc (Section 5.8), respectively, except that they allocate a memory area
that can hold an array of elements of the given length, instead of storage for just a single
element.
-
mallocArray0 :: Storable a => Int -> IO (Ptr a)
-
-
allocaArray0 :: Storable a => Int -> (Ptr a -> IO b) -> IO b
-
reallocArray0 :: Storable a => Ptr a -> Int -> IO (Ptr a)
- These functions are like the previous three functions, but reserve storage space for oneadditional array element to allow for a termination indicator.
-
peekArray :: Storable a => Int -> Ptr a -> IO [a]
- Marshal an array of the given length and starting at the address indicated by the pointer
argument into a Haskell list using Storable.peekElemOff to obtain the individual elements.
The order of elements in the list matches the order in the array.
-
pokeArray :: Storable a => Ptr a -> [a] -> IO ()
- Marshal the elements of the given list into an array whose start address is determined by
the first argument using Storable.pokeElemOff to write the individual elements. The order
of elements in the array matches that in the list.
-
peekArray0 :: (Storable a, Eq a) => a -> Ptr a -> IO [a]
- Marshal an array like peekArray, but instead of the length of the array a terminator element
is specified by the first argument. All elements of the array, starting with the first element,
up to, but excluding the first occurrence of an element that is equal (as determined by ==)
to the terminator are marshalled.
-
pokeArray0 :: Storable a => a -> Ptr a -> [a] -> IO ()
- Marshal an array like pokeArray, but write a terminator value (determined by the first
argument) after the last element of the list. Note that the terminator must not occur in the
marshalled list if it should be possible to extract the list with peekArray0.
-
newArray :: Storable a => [a] -> IO (Ptr a)
-
-
withArray :: Storable a => [a] -> (Ptr a -> IO b) -> IO b
- These two functions combine mallocArray and allocaArray, respectively, with pokeArray;i.e., they allocate a memory area for an array whose length matches that of the list, and
then, marshal the list into that memory area.
-
newArray0 :: Storable a => a -> [a] -> IO (Ptr a)
-
-
withArray0 :: Storable a => a -> [a] -> (Ptr a -> IO b) -> IO b
- These two functions combine mallocArray0 and allocaArray0, respectively, with thefunction pokeArray0; i.e., they allocate a memory area for an array whose length matches
that of the list, and then, marshal the list into that memory area. The first argument
determines the terminator.
-
copyArray :: Storable a => Ptr a -> Ptr a -> Int -> IO ()
-
-
moveArray :: Storable a => Ptr a -> Ptr a -> Int -> IO ()
- These two functions copy entire arrays and behave like the routinesMarshalUtils.copyBytes and MarshalUtils.moveBytes, respectively (Section 5.11). In
particular, moveArray allows the source and destination array to overlap, whereas copyArray
does not allow overlapping arrays. Both functions take a reference to the destination array
as their first, and a reference to the source as their second argument. However, in contrast
to the routines from MarshalUtils the third argument here specifies the number of array
elements (whose type is specified by the parametrised pointer arguments) instead of the
number of bytes to copy.
-
lengthArray0 :: (Storable a, Eq a) => a -> Ptr a -> IO Int
- Determine the length of an array whose end is marked by the first occurrence of the given
terminator (first argument). The length is measured in array elements (not bytes) and does
not include the terminator.
-
advancePtr :: Storable a => Ptr a -> Int -> Ptr a
- Advance a reference to an array by as many array elements (not bytes) as specified.
5.10 MarshalError
The module MarshalError provides language independent routines for converting error conditions of
external functions into Haskell IO monad exceptions. It consists out of two parts. The first part extends
the I/O error facilities of the IO module of the Haskell 98 Library Report with functionality to construct
I/O errors. The second part provides a set of functions that ease turning exceptional result values into
I/O errors.
5.10.1 I/O Errors
The following functions can be used to construct values of type IOError.
-
data IOErrorType
- This is an abstract type that contains a value for each variant of IOError.
-
mkIOError :: IOErrorType -> String -> Maybe Handle -> Maybe FilePath -> IOError
- Construct an IOError of the given type where the second argument describes the error
location and the third and fourth argument contain the file handle and file path of the file
involved in the error if applicable.
-
alreadyExistsErrorType :: IOErrorType
- I/O error where the operation failed because one of its arguments already exists.
-
doesNotExistErrorType :: IOErrorType
- I/O error where the operation failed because one of its arguments does not exist.
-
alreadyInUseErrorType :: IOErrorType
- I/O error where the operation failed because one of its arguments is a single-use resource,
which is already being used.
-
fullErrorType :: IOErrorType
- I/O error where the operation failed because the device is full.
-
eofErrorType :: IOErrorType
- I/O error where the operation failed because the end of file has been reached.
-
illegalOperationType :: IOErrorType
- I/O error where the operation is not possible.
-
permissionErrorType :: IOErrorType
- I/O error where the operation failed because the user does not have sufficient operating
system privilege to perform that operation.
-
userErrorType :: IOErrorType
- I/O error that is programmer-defined.
-
annotateIOError :: IOError -> String -> Maybe Handle -> Maybe FilePath -> IOError
- Adds a location description and maybe a file path and file handle to an I/O error. If any
of the file handle or file path is not given the corresponding value in the I/O error remains
unaltered.
5.10.2 Result Value Checks
The following routines are useful for testing return values and raising an I/O exception in case of values
indicating an error state.
-
throwIf :: (a -> Bool) -> (a -> String) -> IO a -> IO a
- Execute the computation determined by the third argument. If the predicate provided in
the first argument yields True when applied to the result of that computation, raise an IO
exception that includes an error message obtained by applying the second argument to the
result of the computation. If no exception is raised, the result of the computation is the
result of the whole operation.
-
throwIf_:: (a -> Bool) -> (a -> String) -> IO a -> IO ()
- Operate as throwIf does, but discard the result of the computation in any case.
-
throwIfNeg :: (Ord a, Num a) => (a -> String) -> IO a -> IO a
-
-
throwIfNeg_ :: (Ord a, Num a) => (a -> String) -> IO a -> IO ()
- These two functions are instances of throwIf and throwIf_, respectively, where thepredicate is (< 0).
-
throwIfNull :: String -> IO (Ptr a) -> IO (Ptr a)
- This is an instance of throwIf, where the predicate is (== Ptr.nullPtr) and the error
message is constant.
-
void :: IO a -> IO ()
- Discard the result of a computation.
5.11 MarshalUtils
Finally, the module MarshalUtils provides a set of useful auxiliary routines.
-
new :: Storable a => a -> IO (Ptr a)
- This function first applies MarshalAlloc.malloc (Section 5.8) to its argument, and then,
stores the argument in the newly allocated memory area using Storable.poke (Section 5.7).
-
with :: Storable a => a -> (Ptr a -> IO b) -> IO b
- This function is like new, but uses MarshalAlloc.alloca instead of MarshalAlloc.malloc.
-
fromBool :: Num a => Bool -> a
-
-
toBool :: Num a => a -> Bool
- These two functions implement conversions between Haskell Boolean values and numericrepresentations of Boolean values, where False is represented by 0 and True by any non-zero
value.
-
maybeNew :: (a -> IO (Ptr a)) -> (Maybe a -> IO (Ptr a))
- Lift a function that marshals a value of type a to a function that marshals a value of type
Maybe a. In case, where the latter is Nothing, return Ptr.nullPtr (Section 5.4)
-
maybeWith :: (a -> (Ptr b -> IO c) -> IO c)-> (Maybe a -> (Ptr b -> IO c) -> IO c)
- This function lifts a MarshalAlloc.alloca based marshalling function for a to Maybe a. It
marshals values Nothing in the same way as maybeNew.
-
maybePeek :: (Ptr a -> IO b) -> (Ptr a -> IO (Maybe b))
- Given a function that marshals a value stored in the referenced memory area to a value of
type b, lift it to producing a value of type Maybe b. If the pointer is Ptr.nullPtr, produce
Nothing.
-
copyBytes :: Ptr a -> Ptr a -> Int -> IO ()
-
-
moveBytes :: Ptr a -> Ptr a -> Int -> IO ()
- These two functions are Haskell variants of the standard C library routines memcpy() andmemmove(), respectively. As with their C counterparts, moveBytes allows the source and
destination array to overlap, whereas copyBytes does not allow overlapping areas. Both
functions take a reference to the destination area as their first, and a reference to the source
as their second argument--i.e., the argument order is as in an assignment.