From: rrt Date: Mon, 21 Aug 2000 13:13:15 +0000 (+0000) Subject: [project @ 2000-08-21 13:13:15 by rrt] X-Git-Tag: Approximately_9120_patches~3854 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=0f7d86ee694dc724c87bd0225a31be30862c2d29;p=ghc-hetmet.git [project @ 2000-08-21 13:13:15 by rrt] Added a worked example of how to export Haskell functions from a DLL (provided by Sigbj\orn). --- diff --git a/ghc/docs/users_guide/win32-dlls.sgml b/ghc/docs/users_guide/win32-dlls.sgml index ce1cbff..6126708 100644 --- a/ghc/docs/users_guide/win32-dlls.sgml +++ b/ghc/docs/users_guide/win32-dlls.sgml @@ -10,6 +10,11 @@ dynamic link libraries (DLLs) containing ghc-compiled code. This section shows you how to make use of this facility. + +strip seems not to work reliably on DLLs, so it's probably best not to. + + + Linking with DLLs @@ -93,6 +98,10 @@ line. +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. + + + A couple of things to notice: @@ -100,18 +109,15 @@ A couple of things to notice: - - Since DLLs correspond to packages (see ) you need to use when compiling modules that belong to a DLL. If you don't, Haskell code that calls entry points in that DLL will do so incorrectly, and a crash will result. - - + By default, the entry points of all the object files will be exported from the DLL when using . Should you want to constrain this, you can specify the module definition file to use on the command line as follows: @@ -131,38 +137,141 @@ EXPORTS DllRegisterServer = DllRegisterServer@0 DllUnregisterServer = DllUnregisterServer@0 - - - + -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 name of the DLL, as follows: DLL: HScool.dll ==> import lib: libHScool_imp.a - The naming scheme may look a bit weird, but it has the purpose of allowing the co-existence of import libraries with ordinary static libraries (e.g., libHSfoo.a and libHSfoo_imp.a. -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. - + + + + + + +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 + + + + + + +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. + + + +