[project @ 2000-08-21 13:13:15 by rrt]
[ghc-hetmet.git] / ghc / docs / users_guide / win32-dlls.sgml
1 <Chapter id="win32-dlls">
2 <Title>Building and using Win32 DLLs
3 </Title>
4
5 <Para>
6 <IndexTerm><Primary>Dynamic link libraries, Win32</Primary></IndexTerm>
7 <IndexTerm><Primary>DLLs, Win32</Primary></IndexTerm>
8 On Win32 platforms, the compiler is capable of both producing and using
9 dynamic link libraries (DLLs) containing ghc-compiled code. This
10 section shows you how to make use of this facility.
11 </Para>
12
13 <Para>
14 <Command>strip</Command> seems not to work reliably on DLLs, so it's probably best not to.
15 </Para>
16
17
18 <Sect1 id="win32-dlls-link">
19 <Title>Linking with DLLs
20 </Title>
21
22 <Para>
23 The default on Win32 platforms is to link applications in such a way
24 that the executables will use the Prelude and system libraries DLLs,
25 rather than contain (large chunks of) them. This is transparent at the
26 command-line, so 
27 </Para>
28
29 <Para>
30
31 <Screen>
32 sh$ cat main.hs
33 module Main where
34 main = putStrLn "hello, world!"
35 sh$ ghc -o main main.hs
36 ghc: module version changed to 1; reason: no old .hi file
37 sh$ strip main.exe
38 sh$ ls -l main.exe
39 -rwxr-xr-x   1 544      everyone     6144 May  3 17:11 main.exe*
40 sh$ ./main
41 hello, world!
42 sh$ 
43 </Screen>
44
45 </Para>
46
47 <Para>
48 will give you a binary as before, but the <Filename>main.exe</Filename> generated will use the Prelude and RTS DLLs instead.
49 </Para>
50
51 <Para>
52 6K for a <Literal>"hello, world"</Literal> application---not bad, huh? :-)
53 </Para>
54
55 </Sect1>
56
57 <Sect1 id="win32-dlls-linking-static">
58 <Title>Not linking with DLLs
59 <IndexTerm><Primary>-static option (Win32)</Primary></IndexTerm></Title>
60
61 <Para>
62 If you want to build an executable that doesn't depend on any
63 ghc-compiled DLLs, use the <Option>-static</Option> option to link in
64 the code statically.
65 </Para>
66
67 <Para>
68 Notice that you cannot mix code that has been compiled with
69 <Option>-static</Option> and not, so you have to use the <Option>-static</Option>
70 option on all the Haskell modules that make up your application.
71 </Para>
72
73 </Sect1>
74
75 <Sect1 id="win32-dlls-create">
76 <Title>Creating a DLL
77 </Title>
78
79 <Para>
80 <IndexTerm><Primary>Creating a Win32 DLL</Primary></IndexTerm>
81 <IndexTerm><Primary>--mk-dll</Primary></IndexTerm>
82 Sealing up your Haskell library inside a DLL is quite straightforward;
83 compile up the object files that make up the library, and then build
84 the DLL by issuing the following command:
85 </Para>
86
87 <Para>
88 <Screen>
89 ghc --mk-dll -o HSsuper.dll A.o Super.o B.o libmine.a -lgdi32
90 </Screen>
91 </Para>
92
93 <Para>
94 By feeding the ghc compiler driver the option <Option>--mk-dll</Option>, it
95 will build a DLL rather than produce an executable. The DLL will
96 consist of all the object files and archives given on the command
97 line.
98 </Para>
99
100 <Para>
101 To create a `static' DLL, i.e. one that does not depend on the GHC DLLs, compile up your Haskell code using <Option>-static</Option>, and write a <Filename>.def</Filename> file containing the entry points you want to expose (see <XRef LinkEnd="win32-dlls-foreign"> for an example). Then link the DLL adding the <Option>-static</Option> flag, and <Option>-optdll--def=foo.def</Option>, where <Filename>foo.def</Filename> is the name of your <Filename>.def</Filename> file.
102 </Para>
103
104 <Para>
105 A couple of things to notice:
106 </Para>
107
108 <Para>
109
110 <ItemizedList>
111 <ListItem>
112 <Para>
113 Since DLLs correspond to packages (see <XRef LinkEnd="packages">) you need
114 to use <Option>-package-name dll-name</Option> when compiling modules that
115 belong to a DLL. If you don't, Haskell code that calls entry points in that
116 DLL will do so incorrectly, and a crash will result.
117 </Para>
118 </ListItem>
119
120 <ListItem>
121 <Para>
122 By default, the entry points of all the object files will
123 be exported from the DLL when using <Option>--mk-dll</Option>. Should you want to constrain this, you can specify the <Emphasis>module definition file</Emphasis> to use on the command line as follows:
124
125 <Screen>
126 ghc --mk-dll -o .... -optdll--def -optdllMyDef.def
127 </Screen>
128
129 See Microsoft documentation for details, but a module definition file
130 simply lists what entry points you want to export. Here's one that's
131 suitable when building a Haskell COM server DLL:
132
133 <ProgramListing>
134 EXPORTS
135  DllCanUnloadNow     = DllCanUnloadNow@0
136  DllGetClassObject   = DllGetClassObject@12
137  DllRegisterServer   = DllRegisterServer@0
138  DllUnregisterServer = DllUnregisterServer@0
139 </ProgramListing>
140 </Para>
141 </ListItem>
142
143 <ListItem>
144 <Para>
145 In addition to creating a DLL, the <Option>--mk-dll</Option> option also
146 creates an import library. The import library name is derived from the
147 name of the DLL, as follows:
148
149 <ProgramListing>
150 DLL: HScool.dll  ==&#62; import lib: libHScool_imp.a
151 </ProgramListing>
152
153 The naming scheme may look a bit weird, but it has the purpose of
154 allowing the co-existence of import libraries with ordinary static
155 libraries (e.g., <Filename>libHSfoo.a</Filename> and <Filename>libHSfoo&lowbar;imp.a</Filename>.
156
157 Additionally, when the compiler driver is linking in non-static mode, it
158 will rewrite occurrence of <Option>-lHSfoo</Option> on the command line to
159 <Option>-lHSfoo&lowbar;imp</Option>. By doing this for you, switching from
160 non-static to static linking is simply a question of adding
161 <Option>-static</Option> to your command line.
162
163 </Para>
164 </ListItem>
165 </ItemizedList>
166 </Para>
167
168 </Sect1>
169
170
171 <Sect1 id="win32-dlls-foreign">
172 <Title>Making DLLs to be called from other languages</Title>
173
174 <Para>
175
176 If you want to package up Haskell code to be called from other languages,
177 such as Visual Basic or C++, there are some extra things it is useful to
178 know. The dirty details are in the <Emphasis>Foreign Function
179 Interface</Emphasis> definition, but it can be tricky to work out how to
180 combine this with DLL building, so here's an example:
181
182 </Para>
183
184 <ItemizedList>
185
186 <ListItem>
187 <Para>
188 Use <Literal>foreign export</Literal> declarations to export the Haskell functions you want to call from the outside. For example,
189
190 <ProgramListing>
191 module Adder where
192
193 adder :: Int -> Int -> IO Int  -- gratuitous use of IO
194 adder x y = return (x+y)
195
196 foreign export stdcall adder :: Int -> Int -> IO Int
197 </ProgramListing>
198 </Para>
199 </ListItem>
200
201 <ListItem>
202 <Para>
203 Compile it up:
204
205 <Screen>
206 ghc -c adder.hs -fglasgow-exts
207 </Screen>
208   
209 This will produce two files, adder.o and adder_stub.o
210 </Para>
211 </ListItem>
212
213 <ListItem>
214 <Para>
215 compile up a <Function>DllMain()</Function> that starts up the Haskell RTS---a possible implementation is:
216
217 <ProgramListing>
218 #include &lt;windows.h&gt;
219
220 extern void startupHaskell(int , char** );
221
222 static char* args[] = { "ghcDll" };
223
224 BOOL
225 STDCALL
226 DllMain
227    ( HANDLE hModule
228    , DWORD reason
229    , void* reserved
230    )
231 {
232   if (reason == DLL_PROCESS_ATTACH) {
233       /* By now, the RTS DLL should have been hoisted in, but we need to start it up. */
234       startupHaskell(1, args);
235       return TRUE;
236   }
237   return TRUE;
238 }
239 </ProgramListing>
240
241 Compile this up:
242
243 <Screen>
244 gcc -c dllMain.c
245 </Screen>
246 </Para>
247 </ListItem>
248
249 <ListItem>
250 <Para>
251 Construct the DLL:
252
253 <Screen>
254 ghc --mk-dll -o adder.dll adder.o adder_stub.o dllMain.o
255 </Screen>
256
257 </Para>
258 </ListItem>
259
260 <ListItem>
261 <Para>
262 Start using <Function>adder</Function> from VBA---here's how I would <Constant>Declare</Constant> it:
263
264 <ProgramListing>
265 Private Declare adder Lib "adder.dll" Alias "adder@8"
266       (ByVal x As Long, ByVal y As Long) As Long
267 </ProgramListing>
268
269 Since this Haskell DLL depends on a couple of the DLLs that come with GHC,
270 make sure that they are in scope/visible.
271 </Para>
272 </ListItem>
273
274 </ItemizedList>
275
276 </Sect1>
277
278 </Chapter>
279
280 <!-- Emacs stuff:
281      ;;; Local Variables: ***
282      ;;; mode: sgml ***
283      ;;; sgml-parent-document: ("users_guide.sgml" "book" "chapter") ***
284      ;;; End: ***
285  -->