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

Subverting automatic unboxing with "stable pointers"

The arguments of a `_ccall_' are automatically unboxed before the call. There are two reasons why this is usually the Right Thing to do:

It is possible to subvert the unboxing process by creating a "stable pointer" to a value and passing the stable pointer instead. For example, to pass/return an integer lazily to C functions `storeC' and `fetchC', one might write:

storeH :: Int -> IO ()
storeH x = makeStablePtr x              >>= \ stable_x ->
           _ccall_ storeC stable_x

fetchH :: IO Int
fetchH x = _ccall_ fetchC               >>= \ stable_x ->
           deRefStablePtr stable_x      >>= \ x ->
           freeStablePtr stable_x       >>
           return x

The garbage collector will refrain from throwing a stable pointer away until you explicitly call one of the following from C or Haskell.

void freeStablePointer( StgStablePtr stablePtrToToss )
freeStablePtr :: StablePtr a -> IO ()

As with the use of `free' in C programs, GREAT CARE SHOULD BE EXERCISED to ensure these functions are called at the right time: too early and you get dangling references (and, if you're lucky, an error message from the runtime system); too late and you get space leaks.

And to force evaluation of the argument within `fooC', one would call one of the following C functions (according to type of argument).

void     performIO  ( StgStablePtr stableIndex /* StablePtr s (IO ()) */ );
StgInt   enterInt   ( StgStablePtr stableIndex /* StablePtr s Int */ );
StgFloat enterFloat ( StgStablePtr stableIndex /* StablePtr s Float */ );

Note Bene: `_ccall_GC_' must be used if any of these functions are used.


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