on master help sign in
Implement dynamic linking on Windows

There need to be some way to get the calling conventions right to make it really useful. But this will at least unbreak the build for Windows and it works correctly for normal C calls.

commit5a81f99c47274f6eeafa470bba23b4e65a60d42e authorNiklas Larsson <niklas@mm.st> dateSun 7 Apr 2013, 12:31 (14 years ago) parentd1cb783
2 files changed+29−5
idris.cabal+4−1 src/Util/DynamicLinker.hs+25−4
idris.cabal+4−1
@@ -111,7 +111,7 @@ Executable idris
111111 haskeline>=0.7, split, directory,
112112 containers, process, transformers, filepath,
113113 directory, binary, bytestring, text, pretty,
114− language-java>=0.2.2, libffi, unix
114+ language-java>=0.2.2, libffi
115115
116116 Extensions: MultiParamTypeClasses, FunctionalDependencies,
117117 FlexibleInstances, TemplateHaskell
@@ -119,7 +119,10 @@ Executable idris
119119 ghc-options: -rtsopts
120120 if os(linux)
121121 cpp-options: -DLINUX
122+ build-depends: unix
122123 if os(darwin)
123124 cpp-options: -DMACOSX
125+ build-depends: unix
124126 if os(windows)
125127 cpp-options: -DWINDOWS
128+ build-depends: Win32
src/Util/DynamicLinker.hs+25−4
@@ -4,8 +4,14 @@
44module Util.DynamicLinker where
55
66import Foreign.LibFFI
7−import Foreign.Ptr (nullPtr, FunPtr, nullFunPtr)
7+import Foreign.Ptr (nullPtr, FunPtr, nullFunPtr,castPtrToFunPtr)
8+#ifndef WINDOWS
89import System.Posix.DynamicLinker
10+#else
11+import System.Win32.DLL
12+import System.Win32.Types
13+type DL = HMODULE
14+#endif
915
1016hostDynamicLibExt :: String
1117#ifdef LINUX
@@ -16,22 +22,37 @@ hostDynamicLibExt = "dylib"
1622hostDynamicLibExt = "dll"
1723#endif
1824
25+data ForeignFun = forall a. Fun { fun_name :: String
26+ , fun_handle :: FunPtr a
27+ }
28+
1929data DynamicLib = Lib { lib_name :: String
2030 , lib_handle :: DL
2131 }
2232
33+#ifndef WINDOWS
2334tryLoadLib :: String -> IO (Maybe DynamicLib)
2435tryLoadLib lib = do handle <- dlopen (lib ++ "." ++ hostDynamicLibExt) [RTLD_NOW]
2536 if undl handle == nullPtr
2637 then return Nothing
2738 else return . Just $ Lib lib handle
2839
29−data ForeignFun = forall a. Fun { fun_name :: String
30− , fun_handle :: FunPtr a
31− }
3240
3341tryLoadFn :: String -> DynamicLib -> IO (Maybe ForeignFun)
3442tryLoadFn fn (Lib _ h) = do cFn <- dlsym h fn
3543 if cFn == nullFunPtr
3644 then return Nothing
3745 else return . Just $ Fun fn cFn
46+#else
47+tryLoadLib :: String -> IO (Maybe DynamicLib)
48+tryLoadLib lib = do handle <- loadLibrary (lib ++ "." ++ hostDynamicLibExt)
49+ if handle == nullPtr
50+ then return Nothing
51+ else return . Just $ Lib lib handle
52+
53+tryLoadFn :: String -> DynamicLib -> IO (Maybe ForeignFun)
54+tryLoadFn 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