on 9792d64 help sign in
Idris-dev/src/Util/DynamicLinker.hs
58 lines 2.0 kB history raw
1-- | Platform-specific dynamic linking support. Add new platforms to this file
2-- through conditional compilation.
3{-# LANGUAGE ExistentialQuantification, CPP #-}
4module Util.DynamicLinker where
6import Foreign.LibFFI
7import Foreign.Ptr (nullPtr, FunPtr, nullFunPtr,castPtrToFunPtr)
8#ifndef WINDOWS
9import System.Posix.DynamicLinker
10#else
11import System.Win32.DLL
12import System.Win32.Types
13type DL = HMODULE
14#endif
16hostDynamicLibExt :: String
17#ifdef LINUX
18hostDynamicLibExt = "so"
19#elif MACOSX
20hostDynamicLibExt = "dylib"
21#elif WINDOWS
22hostDynamicLibExt = "dll"
23#endif
25data ForeignFun = forall a. Fun { fun_name :: String
26 , fun_handle :: FunPtr a
27 }
29data DynamicLib = Lib { lib_name :: String
30 , lib_handle :: DL
31 }
33#ifndef WINDOWS
34tryLoadLib :: String -> IO (Maybe DynamicLib)
35tryLoadLib lib = do handle <- dlopen (lib ++ "." ++ hostDynamicLibExt) [RTLD_NOW]
36 if undl handle == nullPtr
37 then return Nothing
38 else return . Just $ Lib lib handle
41tryLoadFn :: String -> DynamicLib -> IO (Maybe ForeignFun)
42tryLoadFn fn (Lib _ h) = do cFn <- dlsym h fn
43 if cFn == nullFunPtr
44 then return Nothing
45 else return . Just $ Fun fn cFn
46#else
47tryLoadLib :: String -> IO (Maybe DynamicLib)
48tryLoadLib lib = do handle <- loadLibrary (lib ++ "." ++ hostDynamicLibExt)
49 if handle == nullPtr
50 then return Nothing
51 else return . Just $ Lib lib handle
53tryLoadFn :: String -> DynamicLib -> IO (Maybe ForeignFun)
54tryLoadFn fn (Lib _ h) = do cFn <- getProcAddress h fn
55 if cFn == nullPtr
56 then return Nothing
57 else return . Just $ Fun fn (castPtrToFunPtr cFn)
58#endif