[[project @ 2000-08-21 13:13:15 by rrt]
rrt**20000821131315
Added a worked example of how to export Haskell functions from a DLL
(provided by Sigbj\orn).
] {
hunk ./ghc/docs/users_guide/win32-dlls.sgml 13
+
+strip seems not to work reliably on DLLs, so it's probably best not to.
+
+
+
hunk ./ghc/docs/users_guide/win32-dlls.sgml 100
+
+To create a `static' DLL, i.e. one that does not depend on the GHC DLLs, compile up your Haskell code using , and write a .def file containing the entry points you want to expose (see for an example). Then link the DLL adding the flag, and , where foo.def is the name of your .def file.
+
+
hunk ./ghc/docs/users_guide/win32-dlls.sgml 112
-
hunk ./ghc/docs/users_guide/win32-dlls.sgml 113
-
hunk ./ghc/docs/users_guide/win32-dlls.sgml 117
-
hunk ./ghc/docs/users_guide/win32-dlls.sgml 119
-
hunk ./ghc/docs/users_guide/win32-dlls.sgml 120
+
hunk ./ghc/docs/users_guide/win32-dlls.sgml 140
-
-
hunk ./ghc/docs/users_guide/win32-dlls.sgml 142
-
hunk ./ghc/docs/users_guide/win32-dlls.sgml 143
+
hunk ./ghc/docs/users_guide/win32-dlls.sgml 145
-In addition to creating a DLL, the option will also
-create an import library. The import library name is derived from the
+In addition to creating a DLL, the option also
+creates an import library. The import library name is derived from the
hunk ./ghc/docs/users_guide/win32-dlls.sgml 153
-
hunk ./ghc/docs/users_guide/win32-dlls.sgml 157
-Additionally, when the compiler driver is linking in non-static mode,
-it will rewrite occurrence of on the command line to
-. By doing this for you, switching from non-static
-to static linking is simply a question of adding to
-your command line.
+Additionally, when the compiler driver is linking in non-static mode, it
+will rewrite occurrence of on the command line to
+. By doing this for you, switching from
+non-static to static linking is simply a question of adding
+ to your command line.
hunk ./ghc/docs/users_guide/win32-dlls.sgml 165
-
hunk ./ghc/docs/users_guide/win32-dlls.sgml 166
+
+
+
hunk ./ghc/docs/users_guide/win32-dlls.sgml 170
+
+
+Making DLLs to be called from other languages
+
+
+
+If you want to package up Haskell code to be called from other languages,
+such as Visual Basic or C++, there are some extra things it is useful to
+know. The dirty details are in the Foreign Function
+Interface definition, but it can be tricky to work out how to
+combine this with DLL building, so here's an example:
+
+
+
+
+
+
+
+Use foreign export declarations to export the Haskell functions you want to call from the outside. For example,
+
+
+module Adder where
+
+adder :: Int -> Int -> IO Int -- gratuitous use of IO
+adder x y = return (x+y)
+
+foreign export stdcall adder :: Int -> Int -> IO Int
+
hunk ./ghc/docs/users_guide/win32-dlls.sgml 199
+
+
+
+
+Compile it up:
+
+
+ghc -c adder.hs -fglasgow-exts
+
+
+This will produce two files, adder.o and adder_stub.o
+
+
+
+
+
+compile up a DllMain() that starts up the Haskell RTS---a possible implementation is:
+
+
+#include <windows.h>
+
+extern void startupHaskell(int , char** );
+
+static char* args[] = { "ghcDll" };
+
+BOOL
+STDCALL
+DllMain
+ ( HANDLE hModule
+ , DWORD reason
+ , void* reserved
+ )
+{
+ if (reason == DLL_PROCESS_ATTACH) {
+ /* By now, the RTS DLL should have been hoisted in, but we need to start it up. */
+ startupHaskell(1, args);
+ return TRUE;
+ }
+ return TRUE;
+}
+
+
+Compile this up:
+
+
+gcc -c dllMain.c
+
+
+
+
+
+
+Construct the DLL:
+
+
+ghc --mk-dll -o adder.dll adder.o adder_stub.o dllMain.o
+
+
+
+
+
+
+
+Start using adder from VBA---here's how I would Declare it:
+
+
+Private Declare adder Lib "adder.dll" Alias "adder@8"
+ (ByVal x As Long, ByVal y As Long) As Long
+
+
+Since this Haskell DLL depends on a couple of the DLLs that come with GHC,
+make sure that they are in scope/visible.
+
+
+
+
}