Re: GHC 6.4.1 and Win32 DLLs: Bug in shutdownHaskell?

Did you try to link the DLL statically (i.e. via import library) and remove the call to shutdownHaskell() ? It worked for me (I am using Visual Studio 7, though). Cheers, Cyril ___
I wrapped up some Haskell modules in a Win32 DLL. Loading the DLL dynamically (with LoadLibrary) works fine. However, whether I actually use the library or not, the program (an application with MFC GUI) crashes upon termination. To find the reason for the crash, I added a new function for unloading the DLL using FreeLibrary. FreeLibrary works fine, however the program crashes when it returns to the main event loop. Interestingly, when I reload the library (FreeLibrary followed by LoadLibrary) the program continues working. However, every reload cycle causes the virtual size of the process to increase by about 300K and the fourth reload fails with the error message "getMBlock: VirtualAlloc failed with: 8" (appears in a message window) accompanied by many repetitions of the message "Timer proc: wait failed -- error code: 6" (appears on stderr) and followed by the message "getMBlocks: misaligned block returned" (again in a message window). Then the programm crashes.
Development takes place on Windows XP Professional using MS Visual Studio 6.0 SP 5 and ghc 6.4.1. There are no references from the C++ side to the Haskell heap. I build the DLL using the command
ghc --mk-dll -optdll--def -optdllFoo.def -o Foo.dll Foo.o Foo_stub.o dllMain.c
dllMain.c looks as follows:
#include
#include extern void __stginit_EUzu3820zu85(void);
static char* args[] = { "ghcDll", NULL }; /* N.B. argv arrays must end with NULL */ 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, __stginit_Foo); return TRUE; } else if (reason == DLL_PROCESS_DETACH) { shutdownHaskell(); } return TRUE; }
I played around with hs_exit instead of shutdownHaskell, I moved initialization and clean-up from DllMain to my library loader, nothing helps. Even doing no clean-up whatsoever does not change the behaviour.
Any ideas? Michael
------------------------------
Message: 2 Date: Wed, 01 Mar 2006 12:06:27 -0800 From: Ashley Yakeley
Subject: Re: Missing Folder in ghc? To: glasgow-haskell-users@haskell.org Message-ID: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Simon Marlow wrote:
The configure script has mis-detected your GHC version somehow. Could you look through the output of configure, and see what it says about GHC?
Nothing special:
checking build system type... i686-pc-linux-gnu checking host system type... i686-pc-linux-gnu checking target system type... i686-pc-linux-gnu Canonicalised to: i386-unknown-linux checking for path to top of build tree... /home/ashley/Projects/Collected/Haskell/ghc checking for ghc... /usr/bin/ghc checking version of ghc... 6.4 checking for nhc... no checking for nhc98... no checking for hbc... no
Also look in mk/config.mk, at the value of GhcCanonVersion.
GHC = /usr/bin/ghc GhcDir = $(dir $(GHC)) GhcVersion = 6.4 GhcMajVersion = 6 GhcMinVersion = 4 GhcPatchLevel = 0
# Canonicalised ghc version number, used for easy (integer) version # comparisons. We must expand $(GhcMinVersion) to two digits by # adding a leading zero if necessary: ifneq "$(findstring $(GhcMinVersion), 0 1 2 3 4 5 6 7 8 9)" "" GhcCanonVersion = $(GhcMajVersion)0$(GhcMinVersion) else GhcCanonVersion = $(GhcMajVersion)$(GhcMinVersion) endif
Maybe you switched GHC versions but didn't reconfigure?
I think the problem is that I called autoconf etc. before I called darcs-all get, but not after. Calling autoreconf fixed the problem.

Cyril, - How to generate an import library at all? Section 11.5.1 of the ghc manual says that the --mk-dll option will cause ghc to create such a library, but ghc 6.4.1 does not do this, at least not on Windows. Or did you use the Microsoft lib.exe? (lib.exe /def Foo.def generates an import library from the DLL but I have no idea how use it. After all, lib.exe does not have any type information on the symbols exported by the DLL, so how is this is supposed to work?) - Assuming I have obtained an import library, how to use in the Microsoft world, i.e. how to bridge the gap from .a to .lib? - Is Visual Studio 7 able to process the header files included from the stub header files generated by ghc? Visual Studio 6 has a lot of problems, e.g. it knows nothing about the type long long. - Didn't you have problems with mangled names? - What is the principal difference between using the import library and writing one on my own? Does the import library do anything else than loading the library and delegating the calls? It would be great if you could give me a recipe (in terms of a shell-command sequence) that demonstrates how you achieved your goal! Michael BTW. If I learn anything from this thread that is not yet contained in the Haskell Wiki page pointed to by Simon, I will add it. Cyril Schmidt wrote:
Did you try to link the DLL statically (i.e. via import library) and remove the call to shutdownHaskell() ?
It worked for me (I am using Visual Studio 7, though).
Cheers,
Cyril

Michael,
- How to generate an import library at all? Check this out: http://www.haskell.org/haskellwiki/GHC/FAQ#How_do_I_link_Haskell_with_C.2B.2...
- Assuming I have obtained an import library, how to use in the Microsoft world, i.e. how to bridge the gap from .a to .lib? See above.
- Is Visual Studio 7 able to process the header files included from the stub header files generated by ghc? Visual Studio 6 has a lot of problems, e.g. it knows nothing about the type long long. I could not make Visual Studio 7 understand those, but I didn't try really hard.
- Didn't you have problems with mangled names? Haskell would not understand mangled names. You have to declare the Haskell functions as extern "C" in the C++ code.
This, of course, does not count for functions that are passed to/from Haskell via a function pointer.
- What is the principal difference between using the import library and writing one on my own? Does the import library do anything else than loading the library and delegating the calls? I don't know :(
Just one more piece of advice: if you can compile your C++ code with gcc, you probably can link it statically to the Haskell code, thus avoiding this DLL nightmare. Hope this helps. Cheers Cyril

Cyril, I know the Haskell Wiki page you pointed to; it does not answer my specific questions. The decision which compiler to use is not up to me and, as the Wiki page points out, there is no other way to use Haskell modules from within a Visual Studio C++ compiled application than via a DLL: "The Windows distribution of GHC comes bundled with the GCC compiler, which is used as backend. That's why linking Haskell with Visual C++ is no different from linking GCC-generated code with the code generated by Visual C++. One cannot statically link together object files produced by those two compilers, but they can be linked dynamically: an executable produced by Visual C++ can invoke a DLL produced by GCC, and vice versa." Michael

Michael, Sorry, I might have had wrong assumptions about what you want to do. I presume you have a C++ application compiled via Visual Studio 6 that invokes a Haskell DLL. If that's correct, read on; if not, please tell me again what your setting is. To link your Haskell DLL with the C++ application: 1. Create a .def file for your DLL. Say, your Haskell library is HaskellLib.dll, so your .def file will be HaskelLib.def. Suppose the Haskell finction that you want to call from C++ is myHaskellFunc, then the .def file might look like LIBRARY HASKELLLIB EXPORTS myHaskellFunc 2. Create an import library using Visual Studio's lib.exe: lib /DEF:HaskellLib.def /OUT:HaskellLib.lib 3. Add HaskellLib.lib to your Visual Studio project and link. Cheers, Cyril
Cyril,
I know the Haskell Wiki page you pointed to; it does not answer my specific questions.
The decision which compiler to use is not up to me and, as the Wiki page points out, there is no other way to use Haskell modules from within a Visual Studio C++ compiled application than via a DLL:
"The Windows distribution of GHC comes bundled with the GCC compiler, which is used as backend. That's why linking Haskell with Visual C++ is no different from linking GCC-generated code with the code generated by Visual C++.
One cannot statically link together object files produced by those two compilers, but they can be linked dynamically: an executable produced by Visual C++ can invoke a DLL produced by GCC, and vice versa."
Michael
participants (2)
-
Cyril Schmidt
-
Michael Marte