From: simonmar Date: Mon, 12 Jun 2000 16:13:12 +0000 (+0000) Subject: [project @ 2000-06-12 16:13:12 by simonmar] X-Git-Tag: Approximately_9120_patches~4279 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;ds=sidebyside;h=044b45b02921814abec75709b4a0c6b43f3b9003;p=ghc-hetmet.git [project @ 2000-06-12 16:13:12 by simonmar] Delete whole swathes of old FFI-related stuff, after all no documentation is better than wrong documentation :) --- diff --git a/ghc/docs/users_guide/glasgow_exts.sgml b/ghc/docs/users_guide/glasgow_exts.sgml index 7c262e6..2eaf540 100644 --- a/ghc/docs/users_guide/glasgow_exts.sgml +++ b/ghc/docs/users_guide/glasgow_exts.sgml @@ -1318,7 +1318,7 @@ C. -Please see for more details. +Please see for more details. @@ -1334,7 +1334,7 @@ memory when you're done with it.” -Please see for more details. +Please see for more details. @@ -1476,14 +1476,61 @@ qualifier list has just one element, a boolean expression. - -The foreign interface - - -The foreign interface consists of language and library support. The former -is described later in ; the latter is outlined below, -and detailed in . - + + The foreign interface + + The foreign interface consists of the following components: + + + + The Foreign Function Interface language specification + (included in this manual, in ). + + + + The Foreign module (see ) collects together several interfaces + which are useful in specifying foreign language + interfaces, including the following: + + + + The ForeignObj module (see ), for managing pointers from + Haskell into the outside world. + + + + The StablePtr module (see ), for managing pointers + into Haskell from the outside world. + + + + The CTypes module (see ) gives Haskell equivalents for the + standard C datatypes, for use in making Haskell bindings + to existing C libraries. + + + + The CTypesISO module (see ) gives Haskell equivalents for C + types defined by the ISO C standard. + + + + The Storable library, for + primitive marshalling of data types between Haskell and + the foreign language. + + + + + + +The following sections also give some hints and tips on the use +of the foreign function interface in GHC. Using function headers @@ -1529,590 +1576,6 @@ HsInt lookupEFS (HsForeignObj a, HsInt i); </Sect2> -<Sect2 id="glasgow-stablePtrs"> -<Title>Subverting automatic unboxing with “stable pointers” - - - -stable pointers (Glasgow extension) - - - -The arguments of a _ccall_ automatically unboxed before the -call. There are two reasons why this is usually the Right Thing to -do: - - - - - - - - -C is a strict language: it would be excessively tedious to pass -unevaluated arguments and require the C programmer to force their -evaluation before using them. - - - - - - - Boxed values are stored on the Haskell heap and may be moved -within the heap if a garbage collection occurs—that is, pointers -to boxed objects are not stable. - - - - - - - - -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 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 */ ); - - - - - -performIO -enterInt -enterFloat - - - -Nota Bene: _ccall_GC__ccall_GC_ must be used if any of -these functions are used. - - - - - -Foreign objects: pointing outside the Haskell heap - - - -foreign objects (Glasgow extension) - - - -There are two types that GHC programs can use to reference -(heap-allocated) objects outside the Haskell world: Addr and -ForeignObj. - - - -If you use Addr, it is up to you to the programmer to arrange -allocation and deallocation of the objects. - - - -If you use ForeignObj, GHC's garbage collector will call upon the -user-supplied finaliser function to free the object when the -Haskell world no longer can access the object. (An object is -associated with a finaliser function when the abstract -Haskell type ForeignObj is created). The finaliser function is -expressed in C, and is passed as argument the object: - - - - - -void foreignFinaliser ( StgForeignObj fo ) - - - - - -when the Haskell world can no longer access the object. Since -ForeignObjs only get released when a garbage collection occurs, we -provide ways of triggering a garbage collection from within C and from -within Haskell. - - - - - -void GarbageCollect() -performGC :: IO () - - - - - -More information on the programmers' interface to ForeignObj can be -found in the library documentation. - - - - - -Avoiding monads - - - -C calls to `pure C' -unsafePerformIO - - - -The _ccall_ construct is part of the IO monad because 9 out of 10 -uses will be to call imperative functions with side effects such as -printf. Use of the monad ensures that these operations happen in a -predictable order in spite of laziness and compiler optimisations. - - - -To avoid having to be in the monad to call a C function, it is -possible to use unsafePerformIO, which is available from the -IOExts module. There are three situations where one might like to -call a C function from outside the IO world: - - - - - - - - -Calling a function with no side-effects: - - -atan2d :: Double -> Double -> Double -atan2d y x = unsafePerformIO (_ccall_ atan2d y x) - -sincosd :: Double -> (Double, Double) -sincosd x = unsafePerformIO $ do - da <- newDoubleArray (0, 1) - _casm_ “sincosd( %0, &((double *)%1[0]), &((double *)%1[1]) );” x da - s <- readDoubleArray da 0 - c <- readDoubleArray da 1 - return (s, c) - - - - - - - - - Calling a set of functions which have side-effects but which can -be used in a purely functional manner. - -For example, an imperative implementation of a purely functional -lookup-table might be accessed using the following functions. - - - -empty :: EFS x -update :: EFS x -> Int -> x -> EFS x -lookup :: EFS a -> Int -> a - -empty = unsafePerformIO (_ccall_ emptyEFS) - -update a i x = unsafePerformIO $ - makeStablePtr x >>= \ stable_x -> - _ccall_ updateEFS a i stable_x - -lookup a i = unsafePerformIO $ - _ccall_ lookupEFS a i >>= \ stable_x -> - deRefStablePtr stable_x - - - -You will almost always want to use ForeignObjs with this. - - - - - - - Calling a side-effecting function even though the results will -be unpredictable. For example the trace function is defined by: - - - -trace :: String -> a -> a -trace string expr - = unsafePerformIO ( - ((_ccall_ PreTraceHook sTDERR{-msg-}):: IO ()) >> - fputs sTDERR string >> - ((_ccall_ PostTraceHook sTDERR{-msg-}):: IO ()) >> - return expr ) - where - sTDERR = (“stderr” :: Addr) - - - -(This kind of use is not highly recommended—it is only really -useful in debugging code.) - - - - - - - - - - -C-calling “gotchas” checklist - - - -C call dangers -CCallable -CReturnable - - - -And some advice, too. - - - - - - - - - For modules that use _ccall_s, etc., compile with -.-fvia-C option You don't have to, but you should. - -Also, use the flag (hack) to inform the C -compiler of the fully-prototyped types of all the C functions you -call. ( says more about this…) - -This scheme is the only way that you will get any -typechecking of your _ccall_s. (It shouldn't be that way, but…). -GHC will pass the flag to gcc so that you'll get warnings -if any _ccall_ed functions have no prototypes. - - - - - - -Try to avoid _ccall_s to C functions that take float -arguments or return float results. Reason: if you do, you will -become entangled in (ANSI?) C's rules for when arguments/results are -promoted to doubles. It's a nightmare and just not worth it. -Use doubles if possible. - -If you do use floats, check and re-check that the right thing is -happening. Perhaps compile with and look at -the intermediate C (.hc). - - - - - - - The compiler uses two non-standard type-classes when -type-checking the arguments and results of _ccall_: the arguments -(respectively result) of _ccall_ must be instances of the class -CCallable (respectively CReturnable). Both classes may be -imported from the module CCall, but this should only be -necessary if you want to define a new instance. (Neither class -defines any methods—their only function is to keep the -type-checker happy.) - -The type checker must be able to figure out just which of the -C-callable/returnable types is being used. If it can't, you have to -add type signatures. For example, - - - -f x = _ccall_ foo x - - - -is not good enough, because the compiler can't work out what type x -is, nor what type the _ccall_ returns. You have to write, say: - - - -f :: Int -> IO Double -f x = _ccall_ foo x - - - -This table summarises the standard instances of these classes. - - - - - - - - - -Type -CCallable -CReturnable -Which is probably… - - - -Char - Yes - Yes - unsigned char - - - -Int - Yes - Yes - long int - - - -Word - Yes - Yes - unsigned long int - - - -Addr - Yes - Yes - void * - - - -Float - Yes - Yes - float - - - -Double - Yes - Yes - double - - - -() - No - Yes - void - - - -[Char] - Yes - No - char * (null-terminated) - - - -Array - Yes - No - unsigned long * - - - -ByteArray - Yes - No - unsigned long * - - - -MutableArray - Yes - No - unsigned long * - - - -MutableByteArray - Yes - No - unsigned long * - - - -State - Yes - Yes - nothing! - - - -StablePtr - Yes - Yes - unsigned long * - - - -ForeignObjs - Yes - Yes - see later - - - - - - - -Actually, the Word type is defined as being the same size as a -pointer on the target architecture, which is probably -unsigned long int. - -The brave and careful programmer can add their own instances of these -classes for the following types: - - - - - - -A boxed-primitive type may be made an instance of both -CCallable and CReturnable. - -A boxed primitive type is any data type with a -single unary constructor with a single primitive argument. For -example, the following are all boxed primitive types: - - - -Int -Double -data XDisplay = XDisplay Addr# -data EFS a = EFS# ForeignObj# - - - - - -instance CCallable (EFS a) -instance CReturnable (EFS a) - - - - - - - - - Any datatype with a single nullary constructor may be made an -instance of CReturnable. For example: - - - -data MyVoid = MyVoid -instance CReturnable MyVoid - - - - - - - - - As at version 2.09, String (i.e., [Char]) is still -not a CReturnable type. - -Also, the now-builtin type PackedString is neither -CCallable nor CReturnable. (But there are functions in -the PackedString interface to let you get at the necessary bits…) - - - - - - - - - - - - The code-generator will complain if you attempt to use %r in -a _casm_ whose result type is IO (); or if you don't use %r -precisely once for any other result type. These messages are -supposed to be helpful and catch bugs—please tell us if they wreck -your life. - - - - - - - If you call out to C code which may trigger the Haskell garbage -collector or create new threads (examples of this later…), then you -must use the _ccall_GC__ccall_GC_ primitive or -_casm_GC__casm_GC_ primitive variant of C-calls. (This -does not work with the native code generator—use .) This -stuff is hairy with a capital H! - - - - - - - - -