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