@@ -4,8 +4,14 @@
4module Util.DynamicLinker where
4module Util.DynamicLinker where
6import Foreign.LibFFI
6import Foreign.LibFFI
7−import Foreign.Ptr (nullPtr, FunPtr, nullFunPtr)
7+import Foreign.Ptr (nullPtr, FunPtr, nullFunPtr,castPtrToFunPtr)
8import System.Posix.DynamicLinker
9import System.Posix.DynamicLinker
11+import System.Win32.DLL
12+import System.Win32.Types
10hostDynamicLibExt :: String
16hostDynamicLibExt :: String
11#ifdef LINUX
17#ifdef LINUX
@@ -16,22 +22,37 @@ hostDynamicLibExt = "dylib"
16hostDynamicLibExt = "dll"
22hostDynamicLibExt = "dll"
25+data ForeignFun = forall a. Fun { fun_name :: String
26+ , fun_handle :: FunPtr a
19data DynamicLib = Lib { lib_name :: String
29data DynamicLib = Lib { lib_name :: String
20 , lib_handle :: DL
30 , lib_handle :: DL
23tryLoadLib :: String -> IO (Maybe DynamicLib)
34tryLoadLib :: String -> IO (Maybe DynamicLib)
24tryLoadLib lib = do handle <- dlopen (lib ++ "." ++ hostDynamicLibExt) [RTLD_NOW]
35tryLoadLib lib = do handle <- dlopen (lib ++ "." ++ hostDynamicLibExt) [RTLD_NOW]
25 if undl handle == nullPtr
36 if undl handle == nullPtr
26 then return Nothing
37 then return Nothing
27 else return . Just $ Lib lib handle
38 else return . Just $ Lib lib handle
29−data ForeignFun = forall a. Fun { fun_name :: String
30− , fun_handle :: FunPtr a
33tryLoadFn :: String -> DynamicLib -> IO (Maybe ForeignFun)
41tryLoadFn :: String -> DynamicLib -> IO (Maybe ForeignFun)
34tryLoadFn fn (Lib _ h) = do cFn <- dlsym h fn
42tryLoadFn fn (Lib _ h) = do cFn <- dlsym h fn
35 if cFn == nullFunPtr
43 if cFn == nullFunPtr
36 then return Nothing
44 then return Nothing
37 else return . Just $ Fun fn cFn
45 else return . Just $ Fun fn cFn
47+tryLoadLib :: String -> IO (Maybe DynamicLib)
48+tryLoadLib lib = do handle <- loadLibrary (lib ++ "." ++ hostDynamicLibExt)
51+ else return . Just $ Lib lib handle
53+tryLoadFn :: String -> DynamicLib -> IO (Maybe ForeignFun)
54+tryLoadFn fn (Lib _ h) = do cFn <- getProcAddress h fn
57+ else return . Just $ Fun fn (castPtrToFunPtr cFn)