<chapter id="win32">
<title>Running GHC on Win32 systems</title>
-<sect1>
+<sect1 id="ghc-windows">
<title>
-Starting GHC on Win32 platforms</title>
+Starting GHC on Windows platforms</title>
<para>
The installer that installs GHC on Win32 also sets up the file-suffix associations
</sect1>
-<sect1>
+<sect1 id="ghci-windows">
+<title>Running GHCi on Windows</title>
+
+ <para>We recommend running GHCi in a standard Windows console:
+ select the <literal>GHCi</literal> option from the start menu item
+ added by the GHC installer, or use
+ <literal>Start->Run->cmd</literal> to get a Windows console and
+ invoke <literal>ghci</literal> from there (as long as it's in your
+ <literal>PATH</literal>).</para>
+
+ <para>If you run GHCi in a Cygwin or MSYS shell, then the Control-C
+ behaviour is adversely affected. In one of these environments you
+ should use the <literal>ghcii.sh</literal> script to start GHCi,
+ otherwise when you hit Control-C you'll be returned to the shell
+ prompt but the GHCi process will still be running. However, even
+ using the <literal>ghcii.sh</literal> script, if you hit Control-C
+ then the GHCi process will be killed immediately, rather than
+ letting you interrupt a running program inside GHCi as it should.
+ This problem is caused by the fact that the Cygwin and MSYS shell
+ environments don't pass Control-C events to non-Cygwin child
+ processes, because in order to do that there needs to be a Windows
+ console.</para>
+
+ <para>There's an exception: you can use a Cygwin shell if the
+ <literal>CYGWIN</literal> environment variable does
+ <emphasis>not</emphasis> contain <literal>tty</literal>. In this
+ mode, the Cygwin shell behaves like a Windows console shell and
+ console events are propagated to child processes. Note that the
+ <literal>CYGWIN</literal> environment variable must be set
+ <emphasis>before</emphasis> starting the Cygwin shell; changing it
+ afterwards has no effect on the shell.</para>
+
+ <para>This problem doesn't just affect GHCi, it affects any
+ GHC-compiled program that wants to catch console events. See the
+ <ulink
+ url="&libraryBaseLocation;/GHC-ConsoleHandler.html">GHC.ConsoleHandler</ulink>
+ module.</para>
+</sect1>
+
+<sect1 id="terminal-interaction">
<title>
Interacting with the terminal</title>
</sect1>
-<sect1>
+<sect1 id="library-differences">
<title>
Differences in library behaviour </title>
</para>
</sect1>
-<sect1>
+<sect1 id="ghci-cygwin">
<title>
Using GHC (and other GHC-compiled executables) with cygwin</title>
<para>
<emphasis>Making Haskell libraries into DLLs doesn't work on Windows at the
-moment; however, all the machinery is
-still there. If you're interested, contact the GHC team. Note that
+moment; we hope to re-instate this facility in the future
+(see <xref linkend="using-shared-libs"/>). Note that
building an entire Haskell application as a single DLL is still supported: it's
just multi-DLL Haskell programs that don't work. The Windows
distribution of GHC contains static libraries only.</emphasis></para>
<para>
<indexterm><primary>Creating a Win32 DLL</primary></indexterm>
-<indexterm><primary>––mk-dll</primary></indexterm>
+<indexterm><primary>–shared</primary></indexterm>
Sealing up your Haskell library inside a DLL is straightforward;
compile up the object files that make up the library, and then build
the DLL by issuing a command of the form:
<para>
<screen>
-ghc ––mk-dll -o foo.dll bar.o baz.o wibble.a -lfooble
+ghc –shared -o foo.dll bar.o baz.o wibble.a -lfooble
</screen>
</para>
<para>
-By feeding the ghc compiler driver the option <option>––mk-dll</option>, it
+By feeding the ghc compiler driver the option <option>–shared</option>, it
will build a DLL rather than produce an executable. The DLL will
consist of all the object files and archives given on the command
line.
<listitem>
<para>
By default, the entry points of all the object files will be exported from
-the DLL when using <option>––mk-dll</option>. Should you want to constrain
+the DLL when using <option>–shared</option>. Should you want to constrain
this, you can specify the <emphasis>module definition file</emphasis> to use
on the command line as follows:
<screen>
-ghc ––mk-dll -o .... -optdll––def -optdllMyDef.def
+ghc –shared -o .... MyDef.def
</screen>
See Microsoft documentation for details, but a module definition file
<listitem>
<para>
-In addition to creating a DLL, the <option>––mk-dll</option> option also
+In addition to creating a DLL, the <option>–shared</option> option also
creates an import library. The import library name is derived from the
name of the DLL, as follows:
<programlisting>
-DLL: HScool.dll ==> import lib: libHScool_imp.a
+DLL: HScool.dll ==> import lib: libHScool.dll.a
</programlisting>
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.,
<filename>libHSfoo.a</filename> and
-<filename>libHSfoo_imp.a</filename>.
+<filename>libHSfoo.dll.a</filename>.
Additionally, when the compiler driver is linking in non-static mode, it
will rewrite occurrence of <option>-lHSfoo</option> on the command line to
-<option>-lHSfoo_imp</option>. By doing this for you, switching from
+<option>-lHSfoo.dll</option>. By doing this for you, switching from
non-static to static linking is simply a question of adding
<option>-static</option> to your command line.
<title>Making DLLs to be called from other languages</title>
<para>
-
-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 <emphasis>Foreign Function
-Interface</emphasis> definition, but it can be tricky to work out how to
-combine this with DLL building, so here's an example:
-
+ This section describes how to create DLLs to be called from other languages,
+ such as Visual Basic or C++. This is a special case of
+ <xref linkend="ffi-library" />; we'll deal with the DLL-specific issues that
+ arise below. Here's an example:
</para>
-
-<itemizedlist>
-
-<listitem>
<para>
-Use <literal>foreign export</literal> declarations to export the Haskell
-functions you want to call from the outside. For example,
-
+ Use foreign export declarations to export the Haskell functions you want to
+ call from the outside. For example:
+</para>
<programlisting>
+-- Adder.hs
+{-# LANGUAGE ForeignFunctionInterface #-}
module Adder where
-adder :: Int -> Int -> IO Int –– gratuitous use of IO
+adder :: Int -> Int -> IO Int -- gratuitous use of IO
adder x y = return (x+y)
foreign export stdcall adder :: Int -> Int -> IO Int
</programlisting>
-</para>
-</listitem>
-
-<listitem>
<para>
-Compile it up:
-
-<screen>
-ghc -c adder.hs -fglasgow-exts
-</screen>
-
-This will produce two files, adder.o and adder_stub.o
+ Add some helper code that starts up and shuts down the Haskell RTS:
</para>
-</listitem>
-
-<listitem>
-<para>
-compile up a <function>DllMain()</function> that starts up the Haskell
-RTS-––a possible implementation is:
-
<programlisting>
-#include <windows.h>
+// StartEnd.c
#include <Rts.h>
-extern void__stginit_Adder(void);
-
-static char* args[] = { "ghcDll", NULL };
- /* N.B. argv arrays must end with NULL */
-BOOL
-STDCALL
-DllMain
- ( HANDLE hModule
- , DWORD reason
- , void* reserved
- )
+extern void __stginit_Adder(void);
+
+void HsStart()
{
- 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, __stginit_Adder);
- return TRUE;
- }
- return TRUE;
-}
-</programlisting>
+ int argc = 1;
+ char* argv[] = {"ghcDll", NULL}; // argv must end with NULL
-Here, <literal>Adder</literal> is the name of the root module in the module
-tree (as mentioned above, there must be a single root module, and hence a
-single module tree in the DLL).
+ // Initialize Haskell runtime
+ char** args = argv;
+ hs_init(&argc, &args);
-Compile this up:
+ // Tell Haskell about all root modules
+ hs_add_root(__stginit_Adder);
+}
+void HsEnd()
+{
+ hs_exit();
+}
+</programlisting>
+<para>
+ Here, <literal>Adder</literal> is the name of the root module in the module
+ tree (as mentioned above, there must be a single root module, and hence a
+ single module tree in the DLL). Compile everything up:
+</para>
<screen>
-ghc -c dllMain.c
+ghc -c Adder.hs
+ghc -c StartEnd.c
+ghc -shared -o Adder.dll Adder.o Adder_stub.o StartEnd.o
</screen>
+<para>
+ Now the file <filename>Adder.dll</filename> can be used from other
+ programming languages. Before calling any functions in Adder it is necessary
+ to call <literal>HsStart</literal>, and at the very end call
+ <literal>HsEnd</literal>.
</para>
-</listitem>
-
-<listitem>
<para>
-Construct the DLL:
-
-<screen>
-ghc ––mk-dll -o adder.dll adder.o adder_stub.o dllMain.o
-</screen>
-
+ <emphasis>Warning:</emphasis> It may appear tempting to use
+ <literal>DllMain</literal> to call
+ <literal>hs_init</literal>/<literal>hs_exit</literal>, but this won't work
+ (particularly if you compile with <literal>-threaded</literal>). There are
+ severe restrictions on which actions can be performed during
+ <literal>DllMain</literal>, and <literal>hs_init</literal> violates these
+ restrictions, which can lead to your dll freezing during startup (see
+ <ulink url="http://hackage.haskell.org/trac/ghc/ticket/3605">bug
+ #3605</ulink>).
</para>
-</listitem>
-<listitem>
-<para>
-Start using <function>adder</function> from VBA-––here's how I would
-<constant>Declare</constant> it:
+<sect3 id="win32-dlls-vba">
+<title>Using from VBA</title>
+<para>
+ An example of using <filename>Adder.dll</filename> from VBA is:
+</para>
<programlisting>
-Private Declare Function adder Lib "adder.dll" Alias "adder@8"
+Private Declare Function Adder Lib "Adder.dll" Alias "adder@8" _
(ByVal x As Long, ByVal y As Long) As Long
-</programlisting>
-Since this Haskell DLL depends on a couple of the DLLs that come with GHC,
-make sure that they are in scope/visible.
+Private Declare Sub HsStart Lib "Adder.dll" ()
+Private Declare Sub HsEnd Lib "Adder.dll" ()
+
+Private Sub Document_Close()
+HsEnd
+End Sub
+
+Private Sub Document_Open()
+HsStart
+End Sub
+
+Public Sub Test()
+MsgBox "12 + 5 = " & Adder(12, 5)
+End Sub
+</programlisting>
+<para>
+ This example uses the
+ <literal>Document_Open</literal>/<literal>Close</literal> functions of
+ Microsoft Word, but provided <literal>HsStart</literal> is called before the
+ first function, and <literal>HsEnd</literal> after the last, then it will
+ work fine.
</para>
+</sect3>
+
+<sect3 id="win32-dlls-c++">
+<title>Using from C++</title>
<para>
-Building statically linked DLLs is the same as in the previous section: it
-suffices to add <option>-static</option> to the commands used to compile up
-the Haskell source and build the DLL.
+ An example of using <filename>Adder.dll</filename> from C++ is:
</para>
-</listitem>
+<programlisting>
+// Tester.cpp
+#include "HsFFI.h"
+#include "Adder_stub.h"
+#include <stdio.h>
+
+extern "C" {
+ void HsStart();
+ void HsEnd();
+}
-</itemizedlist>
+int main()
+{
+ HsStart();
+ // can now safely call functions from the DLL
+ printf("12 + 5 = %i\n", adder(12,5)) ;
+ HsEnd();
+ return 0;
+}
+</programlisting>
+<para>
+ This can be compiled and run with:
+</para>
+<screen>
+$ ghc -o tester Tester.cpp Adder.dll.a
+$ tester
+12 + 5 = 17
+</screen>
+
+</sect3>
</sect2>
<!-- Emacs stuff:
;;; Local Variables: ***
- ;;; mode: xml ***
;;; sgml-parent-document: ("users_guide.xml" "book" "chapter") ***
;;; End: ***
-->