RE: [Haskell-cafe] FFI and Excel VBA
I was able to figure out how to get the example in chapter 11 of the GHC manual to work. Since it was not intuitive (to a non C programmer), I thought that I should post this so that others might take advantage of it. 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 suber hello -------------------------------------------- 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. I hope that this was helpful. -Darrell Lewis-Sandy
participants (1)
-
Lewis-Sandy, Darrell