summaryrefslogtreecommitdiff
path: root/docs/users_guide/win32-dlls.xml
diff options
context:
space:
mode:
Diffstat (limited to 'docs/users_guide/win32-dlls.xml')
-rw-r--r--docs/users_guide/win32-dlls.xml575
1 files changed, 0 insertions, 575 deletions
diff --git a/docs/users_guide/win32-dlls.xml b/docs/users_guide/win32-dlls.xml
deleted file mode 100644
index 1168871c10..0000000000
--- a/docs/users_guide/win32-dlls.xml
+++ /dev/null
@@ -1,575 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<chapter id="win32">
-<title>Running GHC on Win32 systems</title>
-
-<sect1 id="ghc-windows">
-<title>
-Starting GHC on Windows platforms</title>
-
-<para>
-The installer that installs GHC on Win32 also sets up the file-suffix associations
-for ".hs" and ".lhs" files so that double-clicking them starts <command>ghci</command>.
-</para>
-<para>
-Be aware of that <command>ghc</command> and <command>ghci</command> do
-require filenames containing spaces to be escaped using quotes:
-<programlisting>
- c:\ghc\bin\ghci "c:\\Program Files\\Haskell\\Project.hs"
-</programlisting>
-If the quotes are left off in the above command, <command>ghci</command> will
-interpret the filename as two, "c:\\Program" and "Files\\Haskell\\Project.hs".
-</para>
-
-<!-- not clear whether there are current editions of Win32 OSes that
- doesn't do this by default.
-
-<para> Solution: don't use "Open With...", avoid spaces in file names,
-or fiddle with the appropriate registry setting:
-<programlisting>
- HKEY_CLASSES_ROOT\Unknown\shell\openas\command
-</programlisting>
-Notice how the "%1" argument is quoted (or not).
-</para>
-<para> This problem doesn't occur when double-clicking.
-</para>
--->
-
-</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>
-
-<para>By default GHC builds applications that open a console window when they start.
-If you want to build a GUI-only application, with no console window, use the flag
-<literal>-optl-mwindows</literal> in the link step.
-</para>
-
-<para> <emphasis>Warning:</emphasis> Windows GUI-only programs have no
- stdin, stdout or stderr so using the ordinary Haskell
- input/output functions will cause your program to fail with an
- IO exception, such as:
-<screen>
- Fail: &lt;stdout&gt;: hPutChar: failed (Bad file descriptor)
-</screen>
- However using Debug.Trace.trace is alright because it uses
- Windows debugging output support rather than stderr.</para>
-
-<para>For some reason, Mingw ships with the <literal>readline</literal> library,
-but not with the <literal>readline</literal> headers. As a result, GHC (like Hugs) does not
-use <literal>readline</literal> for interactive input on Windows.
-You can get a close simulation by using an emacs shell buffer!
-</para>
-
-</sect1>
-
-<sect1 id="library-differences">
-<title>
-Differences in library behaviour </title>
-
-<para>
-Some of the standard Haskell libraries behave slightly differently on Windows.
-
-<itemizedlist>
-<listitem> <para>
-On Windows, the '<literal>^Z</literal>' character is interpreted as an
-end-of-file character, so if you read a file containing this character
-the file will appear to end just before it. To avoid this,
-use <literal>IOExts.openFileEx</literal> to open a file in binary
-(untranslated) mode or change an already opened file handle into
-binary mode using <literal>IOExts.hSetBinaryMode</literal>. The
-<literal>IOExts</literal> module is part of the
-<literal>lang</literal> package.
-</para>
-</listitem>
-</itemizedlist>
-</para>
-</sect1>
-
-<sect1 id="ghci-cygwin">
-<title>
-Using GHC (and other GHC-compiled executables) with cygwin</title>
-
-<sect2>
-<title>Background</title> <para>The cygwin tools aim to provide a
-unix-style API on top of the windows libraries, to facilitate ports of
-unix software to windows. To this end, they introduce a unix-style
-directory hierarchy under some root directory (typically
-<filename>/</filename> is <filename>C:\cygwin\</filename>). Moreover,
-everything built against the cygwin API (including the cygwin tools
-and programs compiled with cygwin's ghc) will see / as the root of
-their file system, happily pretending to work in a typical unix
-environment, and finding things like <filename>/bin</filename> and <filename>/usr/include</filename> without
-ever explicitly bothering with their actual location on the windows
-system (probably <filename>C:\cygwin\bin</filename> and <filename>C:\cygwin\usr\include</filename>).
-</para>
-</sect2>
-
-<sect2><title>The problem</title>
-<para>GHC, by default, no longer depends on cygwin, but is a native
-windows program. It is built using mingw, and it uses mingw's ghc
-while compiling your Haskell sources (even if you call it from
-cygwin's bash), but what matters here is that - just like any other
-normal windows program - neither GHC nor the executables it produces
-are aware of cygwin's pretended unix hierarchy. GHC will happily
-accept either '/' or '\' as path separators, but it won't know where
-to find <filename>/home/joe/Main.hs</filename> or <filename>/bin/bash</filename>
-or the like. This causes all
-kinds of fun when GHC is used from within cygwin's bash, or in
-make-sessions running under cygwin.
-</para>
-</sect2>
-
-<sect2><title>Things to do</title>
-<itemizedlist>
-<listitem>
-<para> Don't use absolute paths in make, configure &amp; co if there is any chance
- that those might be passed to GHC (or to GHC-compiled programs). Relative
- paths are fine because cygwin tools are happy with them and GHC accepts
- '/' as path-separator. And relative paths don't depend on where cygwin's
- root directory is located, or on which partition or network drive your source
- tree happens to reside, as long as you 'cd' there first.
-</para></listitem>
-
-<listitem>
-<para> If you have to use absolute paths (beware of the innocent-looking
- <literal>ROOT=`pwd`</literal> in makefile hierarchies or configure scripts), cygwin provides
- a tool called <command>cygpath</command> that can convert cygwin's unix-style paths to their
- actual windows-style counterparts. Many cygwin tools actually accept
- absolute windows-style paths (remember, though, that you either need
- to escape '\' or convert '\' to '/'), so you should be fine just using those
- everywhere. If you need to use tools that do some kind of path-mangling
- that depends on unix-style paths (one fun example is trying to interpret ':'
- as a separator in path lists..), you can still try to convert paths using
- <command>cygpath</command> just before they are passed to GHC and friends.
-</para></listitem>
-
-<listitem>
-<para> If you don't have <command>cygpath</command>, you probably don't have cygwin and hence
- no problems with it... unless you want to write one build process for several
- platforms. Again, relative paths are your friend, but if you have to use
- absolute paths, and don't want to use different tools on different platforms,
- you can simply write a short Haskell program to print the current directory
- (thanks to George Russell for this idea): compiled with GHC, this will give
- you the view of the file system that GHC depends on (which will differ
- depending on whether GHC is compiled with cygwin's gcc or mingw's
- gcc or on a real unix system..) - that little program can also deal with
- escaping '\' in paths. Apart from the banner and the startup time,
- something like this would also do:
-<programlisting>
- $ echo "Directory.getCurrentDirectory >>= putStrLn . init . tail . show " | ghci
-</programlisting>
-</para></listitem>
-</itemizedlist>
-</sect2>
-</sect1>
-
-
-<sect1 id="win32-dlls">
-<title>Building and using Win32 DLLs
-</title>
-
-<para>
-<indexterm><primary>Dynamic link libraries, Win32</primary></indexterm>
-<indexterm><primary>DLLs, Win32</primary></indexterm>
-On Win32 platforms, the compiler is capable of both producing and using
-dynamic link libraries (DLLs) containing ghc-compiled code. This
-section shows you how to make use of this facility.
-</para>
-
-<para>
-There are two distinct ways in which DLLs can be used:
-<itemizedlist>
- <listitem>
- <para>
- You can turn each Haskell package into a DLL, so that multiple
- Haskell executables using the same packages can share the DLL files.
- (As opposed to linking the libraries statically, which in effect
- creates a new copy of the RTS and all libraries for each executable
- produced.)
- </para>
- <para>
- That is the same as the dynamic linking on other platforms, and it
- is described in <xref linkend="using-shared-libs"/>.
- </para>
- </listitem>
- <listitem>
- <para>
- You can package up a complete Haskell program as a DLL, to be called
- by some external (usually non-Haskell) program. This is usually used
- to implement plugins and the like, and is described below.
- </para>
- </listitem>
-</itemizedlist>
-</para>
-
-<!--
-<para>
-Until recently, <command>strip</command> didn't work reliably on DLLs, so you
-should test your version with care, or make sure you have the latest
-binutils. Unfortunately, we don't know exactly which version of binutils
-cured the problem (it was supposedly fixed some years ago).
-</para>
-
-
-<sect2 id="win32-dlls-link">
-<title>Linking with DLLs</title>
-
-<para>
-The default on Win32 platforms is to link applications in such a way
-that the executables will use the Prelude and system libraries DLLs,
-rather than contain (large chunks of) them. This is transparent at the
-command-line, so
-</para>
-
-<para>
-<screen>
-sh$ cat main.hs
-module Main where
-main = putStrLn "hello, world!"
-sh$ ghc -o main main.hs
-ghc: module version changed to 1; reason: no old .hi file
-sh$ strip main.exe
-sh$ ls -l main.exe
--rwxr-xr-x 1 544 everyone 4608 May 3 17:11 main.exe*
-sh$ ./main
-hello, world!
-sh$
-</screen>
-</para>
-
-<para>
-will give you a binary as before, but the <filename>main.exe</filename>
-generated will use the Prelude and RTS DLLs instead of linking them in
-statically.
-</para>
-
-<para>
-4K for a <literal>"hello, world"</literal> application&mdash;not bad, huh? :-)
-</para>
-
-</sect2>
-
-<sect2 id="win32-dlls-linking-static">
-<title>Not linking with DLLs
-<indexterm><primary>-static option (Win32)</primary></indexterm></title>
-
-<para>
-If you want to build an executable that doesn't depend on any
-ghc-compiled DLLs, use the <option>-static</option> option to link in
-the code statically.
-</para>
-
-<para>
-Notice that you cannot mix code that has been compiled with
-<option>-static</option> and not, so you have to use the <option>-static</option>
-option on all the Haskell modules that make up your application.
-</para>
-
-</sect2>
--->
-
-<sect2 id="win32-dlls-create">
-<title>Creating a DLL</title>
-
-<para>
-<indexterm><primary>Creating a Win32 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>
-
-<para>
-<screen>
-ghc -shared -o foo.dll bar.o baz.o wibble.a -lfooble
-</screen>
-</para>
-
-<para>
-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.
-</para>
-
-<!--
-<para>
-To create a `static' DLL, i.e. one that does not depend on the GHC DLLs,
-use the <option>-static</option> when compiling up your Haskell code and
-building the DLL.
-</para>
--->
-
-<para>
-A couple of things to notice:
-</para>
-
-<para>
-
-<itemizedlist>
-<!--
-<listitem>
-<para>
-Since DLLs correspond to packages (see <xref linkend="packages"/>) you need
-to use <option>-package-name dll-name</option> when compiling modules that
-belong to a DLL if you're going to call them from Haskell. Otherwise, Haskell
-code that calls entry points in that DLL will do so incorrectly, and crash.
-For similar reasons, you can only compile a single module tree into a DLL,
-as <function>startupHaskell</function> needs to be able to call its
-initialisation function, and only takes one such argument (see <xref
-linkend="win32-dlls-foreign"/>). Hence the modules
-you compile into a DLL must have a common root.
-</para>
-</listitem>
--->
-
-<listitem>
-<para>
-By default, the entry points of all the object files will be exported from
-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 -shared -o .... MyDef.def
-</screen>
-
-See Microsoft documentation for details, but a module definition file
-simply lists what entry points you want to export. Here's one that's
-suitable when building a Haskell COM server DLL:
-
-<programlisting>
-EXPORTS
- DllCanUnloadNow = DllCanUnloadNow@0
- DllGetClassObject = DllGetClassObject@12
- DllRegisterServer = DllRegisterServer@0
- DllUnregisterServer = DllUnregisterServer@0
-</programlisting>
-</para>
-</listitem>
-
-<listitem>
-<para>
-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 ==&#62; 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.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.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.
-
-</para>
-</listitem>
-</itemizedlist>
-</para>
-
-</sect2>
-
-
-<sect2 id="win32-dlls-foreign">
-<title>Making DLLs to be called from other languages</title>
-
-<para>
- 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>
-<para>
- 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 x y = return (x+y)
-
-foreign export stdcall adder :: Int -> Int -> IO Int
-</programlisting>
-<para>
- Add some helper code that starts up and shuts down the Haskell RTS:
-</para>
-<programlisting>
-// StartEnd.c
-#include &lt;Rts.h&gt;
-
-void HsStart()
-{
- int argc = 1;
- char* argv[] = {"ghcDll", NULL}; // argv must end with NULL
-
- // Initialize Haskell runtime
- char** args = argv;
- hs_init(&amp;argc, &amp;args);
-}
-
-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 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>
-<para>
- <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://ghc.haskell.org/trac/ghc/ticket/3605">bug
- #3605</ulink>).
-</para>
-
-<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" _
- (ByVal x As Long, ByVal y As Long) As Long
-
-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 = " &amp; 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>
- An example of using <filename>Adder.dll</filename> from C++ is:
-</para>
-
-<programlisting>
-// Tester.cpp
-#include "HsFFI.h"
-#include "Adder_stub.h"
-#include &lt;stdio.h&gt;
-
-extern "C" {
- void HsStart();
- void HsEnd();
-}
-
-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>
-
-</sect1>
-</chapter>
-
-<!-- Emacs stuff:
- ;;; Local Variables: ***
- ;;; sgml-parent-document: ("users_guide.xml" "book" "chapter") ***
- ;;; ispell-local-dictionary: "british" ***
- ;;; End: ***
- -->