2
votes

I am learning how to use the FFI and am starting with a very simple example, calling a C function from Haskell.

This is all under Windows 7, 64-bit, Visual Studio Community 2013.

The C looks like this:

_declspec(dllexport) int line(int m, int b, int x) {
    return m * x + b;
}

I've set the VS compiler to generate a 64-bit DLL and it does so, one named simpleclib.dll (there's also the matching .lib file, too)

The matching Haskell looks like this:

module Main (main) where

foreign import ccall "line" cline :: Int -> Int -> Int -> Int

main = do
    putStr "hello,world\n"
    putStr (show y)

y = cline 2 5 10

GHC was downloaded within the last month, 7.8.3.

The command line for ghc is this:

c:\> ghc foreign -L. -lsimpleclib

This runs successfully, generating a .EXE as expected.

Running the program produces an app crash on a BEX64:

Problem Event Name: BEX64 Application Name: foreign.exe Application Version: 0.0.0.0 Application Timestamp: 551048a6 Fault Module Name: StackHash_0981 Fault Module Version: 0.0.0.0 Fault Module Timestamp: 00000000 Exception Offset: 0000000000000000 Exception Code: c0000005 Exception Data: 0000000000000008 OS Version: 6.1.7601.2.1.0.256.4 Locale ID: 1033 Additional Information 1: 0981 Additional Information 2: 09817cdf87ca03322f39545f3e74c62d Additional Information 3: 31c0 Additional Information 4: 31c0a543af0be952ecd86b6ee71cc83a

I've also tried using Data.Int.Int64's for the parameter definition. Same result.

Anyone have any ideas?

Thanks, cww

2
Use CInt, not Int. Not sure if that's the only problem, never tried to link to a windows dll. - Cubic
Good thought. Just tried it. Same result. So far, I've tried Int, CInt, Int32, and Int64 thinking that it may be some sort of stack misalignment thing. All give the same result. A slightly deeper look into the debugger reveals that the root problem is an access violation at (of course) 0x0000000000000000 (a 64 bit 0). Strange, because I don't see any obvious adjustment that can be made. - collumww

2 Answers

1
votes

I can't find the knob to tell VS to create a 64 bit dll, so I tried gcc (on Win 7, 64 bit). I had to change the first line of your c program in 2 ways, add a __cdecl, and made the _cdecl have 2 underscores: __declspec(dllexport) int __cdecl line(int m, int b, int x) {

C:\...\>foreign
hello,world
25

`

0
votes

It is actually a bug in binutils that VS-generated 64-bit import libraries (.lib coming with .dll). See the discussion here: https://ghc.haskell.org/trac/ghc/ticket/10885#comment:6

The bug can be worked around by replacing binutils in the GHC distribution with the ones from MSys2. Alternatively, the linker usually is able to link the .dll files directly, without the .lib files. This works for me for small examples but bigger may fail — I do not recommend taking this approach.