2

I need to call a string function from C# like the one below:

{-# LANGUAGE ForeignFunctionInterface #-}

module ParserIO where

import Foreign
import Foreign.C.Types
import Foreign.C.String
import ParserFuncs

wrapHello :: String -> IO CString
wrapHello name = newCString $ hello name

hiThere :: CString -> IO CString
hiThere name = peekCString name >>= wrapHello

foreign export ccall hiThere ::  CString -> IO CString

The calling code is as follows:

public sealed class HaskellInterOp : IDisposable {
    [DllImport("HSdll.dll", CallingConvention = CallingConvention.Cdecl)]
    private static extern void hs_init(IntPtr argc, IntPtr argv);

    [DllImport("HSdll.dll", CallingConvention = CallingConvention.Cdecl)]
    private static extern void hs_exit();

    [DllImport("HSdll.dll", CallingConvention = CallingConvention.Cdecl)]
    private static extern String hiThere(String name);


    public HaskellInterOp() {
        hs_init(IntPtr.Zero, IntPtr.Zero); 
    }

    public void Dispose() {
        hs_exit(); 
    }

    public String Hello(string name) {
        var result = "Hi";  //hiThere(name);
        return result;
    }
}

I have tried various combinations of from: Calling Haskell from C# and Call a Haskell function in .NET without success.

I am using the following to compile the DLL (ghc version 7.10.2):

ghc --make -shared ParserIO.hs

But when the dll produced is called it fails when it is loading in C# I get:

Result Message: System.BadImageFormatException : An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B).

Here is the test code:

   [Test]
    public void when_interop_is_called_then_the_result_is_as_expected() {
        using (var io = new HaskellInterOp()) {
           var greeting = io.Hello("John");
           Assert.AreEqual("Hello John", greeting);
       }
    }

I figure because my ap needs to be 32 bit and the HSdll.dlld is 64. Is there a way to get GHC to generate a 32 Bit DLL that can be called from my 32 Bit C# ap?

Thanks

John

Community
  • 1
  • 1
John Walker
  • 513
  • 4
  • 16
  • 1
    Use the 32-bit version of GHC if you want a 32-bit output. (You can build GHCs in other configurations, like a 64-bit GHC that produces 32-bit output, but there are no such binaries provided for download.) – Reid Barton Nov 21 '15 at 13:33
  • I must still be doing something wrong: I've downloaded and installed: https://www.haskell.org/ghc/dist/7.6.1/ghc-7.6.1-i386-windows.exe and changed my command line to point to the location of this version of ghc: C:\ghc32\ghc-7.6.1\bin\ghc --make -shared ParserIO.hs But dependency walker is still showing HSdll.dll as 64 bit and the app is still failing when the dll is loaded (though now with no message or call stack). My test "Hello" function is not calling the dll yet so it must be the load that is failing – John Walker Nov 22 '15 at 01:16

0 Answers0