[[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. + + + + }