[Haskell-cafe] FFI and Excel VBA

Jason Dagit dagit at codersbase.com
Thu Jun 21 13:15:22 EDT 2007


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 <darrelll at amgen.com> wrote:
> 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 <windows.h>
> #include <Rts.h>
>
> 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 at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>


More information about the Haskell-Cafe mailing list