RE: [Haskell-cafe] FFI and Excel VBA

Whoops - I posted the wrong version of the exports list. Compilation with
that adder.def will fail (since it the Haskell code doesn't export either
suber or hello). Below is the revised example:
KEYWORDS: Foreign, Export, Win32, DLL, VBA, Excel, GCH, Example
The contents of adder.hs are as follows:
--------------------------------------------
module Adder(adder) where
import Foreign
adder :: Int -> Int -> IO Int
adder x y = return (id$!(x+y))
foreign export stdcall adder :: Int -> Int -> IO Int
--------------------------------------------
The contents of the dllMain.c file are below:
--------------------------------------------
#include

Darrell,
Would you be willing to put your step by step instructions on the
wiki? I think having them on the wiki would benefit the largest
audience.
Thanks!
Jason
On 6/21/07, Lewis-Sandy, Darrell
Whoops - I posted the wrong version of the exports list. Compilation with that adder.def will fail (since it the Haskell code doesn't export either suber or hello). Below is the revised example:
KEYWORDS: Foreign, Export, Win32, DLL, VBA, Excel, GCH, Example
The contents of adder.hs are as follows: -------------------------------------------- module Adder(adder) where
import Foreign
adder :: Int -> Int -> IO Int adder x y = return (id$!(x+y))
foreign export stdcall adder :: Int -> Int -> IO Int --------------------------------------------
The contents of the dllMain.c file are below: --------------------------------------------
#include
#include extern void __stginit_Adder(void);
static char* args[] = { "ghcDll", NULL };
BOOL STDCALL DllMain ( HANDLE hModule, DWORD reason, void* reserved ) { if (reason == DLL_PROCESS_ATTACH) { startupHaskell(1, args, __stginit_Adder); return TRUE; }
if (reason == DLL_PROCESS_DETACH) { shutdownHaskell(); return TRUE; }
return TRUE; }
-------------------------------------------- Note that the GHC manual omits the space between the "void" and the __stgint_Adder(void) which causes a compile error. The second case (if (reason == DLL_PROCESS_DETACH) is essential for garbage collection, and shuts down the Haskell runtime when the DLL is unloaded.
To execute the Haskell code, I created a VBA module in an Excel workbook with the following code snippet: -------------------------------------------- Private Declare Function adder Lib "adder.dll" _ (ByVal x As Integer, ByVal y As Integer) As Integer
Private Sub test() Debug.Print adder(1, 2) End Sub -------------------------------------------- NOTE: If the dll is not ultimately placed in your environments' PATH, then you may have to modify the library name to include the actual path information (or else you will get an error indicating that the library can't be found). Example: ... adder Lib "c:\myDlls\adder\adder.dll" ...
Finally, you need to explicitly define an exports file to keep the c compiler from mangling the names too badly. The contents of adder.def are as follows: -------------------------------------------- EXPORTS adder --------------------------------------------
With these preliminaries out of the way, you can compile this to a dll using the following sequence of commands: -------------------------------------------- ghc -c adder.hs -fglasgow-exts ghc -c dllMain.c ghc --mk-dll -optdll--def=adder.def -o adder.dll adder.o adder_stub.o dllMain.o --------------------------------------------
When this is all done, open the XLProject and press F5 to run, or simply type "=adder(1,2)" in any cell of the workbook.
My apologies for any confusion caused by my earlier posting.
-Darrell Lewis-Sandy _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (2)
-
Jason Dagit
-
Lewis-Sandy, Darrell