Next Previous Contents

2.2 Naming the external function

The name of the external function consists of two parts, one specifying its location, the other its name:

ext_fun  : ext_loc ext_name
         | ext_name

ext_name : string
ext_loc  : string

For example,

foreign import stdcall "Advapi32" "RegCloseKey" regCloseKey :: Addr -> IO ()

states that the external function named RegCloseKey at location Advapi32 should be bound to the Haskell name regCloseKey. For a Win32 Haskell implementation that supports the loading of DLLs on-the-fly, this declaration will most likely cause the run-time system to load the Advapi32.dll DLL before looking up the function RegCloseKey() therein to get at the function pointer to use when invoking regCloseKey.

Compiled implementations may do something completely different, i.e., mangle "RegCloseKey" to convert it into an archive/import library symbol, that's assumed to be in scope when linking. The details of which are platform (and compiler command-line) dependent.

If the location part is left out, the name of the external function specifies a symbol that is assumed to be in scope when linking.

The location part can either contain an absolute `address' (i.e., path) of the archive/DLL, or just its name, leaving it up to the underlying system (system meaning both RTS/compiler and OS) to resolve the name to its real location.

An implementation is expected to be able to intelligently transform the ext_loc location to fit platform-specific practices for naming dynamic libraries. For instance, given the declaration

foreign import "Foo" "foo" foo :: Int -> Int -> IO ()

an implementation should map "Foo" to "Foo.dll" on a Win32 platform, and "libFoo.so" on ELF platforms. If the lookup of the dynamic library with this transformed location name should fail, the implementation should then attempt to use the original name before eventually giving up. As part of their documentation, implementations of foreign import should specify the exact details of how ext_locs are transformed and resolved, including the list of directories searched (and the order in which they are.)

In the case the Haskell name of the imported function is identical to the external name, the ext_fun can be omitted. i.e.,

foreign import sin :: Double -> IO Double

is identical to

foreign import "sin" sin :: Double -> IO Double


Next Previous Contents