I am trying to learn how to interface Haskell and C. To start it out, I wrote Inc.hs
, the simplest thing I can conceive:
{-# LANGUAGE ForeignFunctionInterface #-}
module Inc where
import Foreign
import Foreign.C.Types
inc :: Int -> Int
inc = (+1)
foreign export ccall cinc :: CInt -> CInt
cinc :: CInt -> CInt
cinc = fromIntegral . inc . fromIntegral
And compiled it to produce Inc_stub.h
:
ghc -c Inc.hs
Worked fine. I then wrote the C file, also trying to be as simple as humanly possible:
#include <stdio.h>
#include "Inc_stub.h"
int main(int argc, char *argv[]) {
int a = 1;
hs_init(&argc, &argv);
a = cinc(a);
hs_exit();
if (a == 2) {
puts("Worked!");
}
return 0;
}
Tried to compile it, got this linker error:
ghc -no-hs-main inc.c Inc -o simplest
Linking simplest.exe ...
inc.o:inc.c:(.text+0x0): multiple definition of `main'
Inc.o:inc.c:(.text+0x0): first defined here
Inc.o:inc.c:(.text+0x31): undefined reference to `cinc'
c:/program files/haskell platform/7.10.2-a/mingw/bin/../lib/gcc/x86_64-w64-mingw32/4.6.3/../../../../x86_64-w64-mingw32/bin/ld.exe: Inc.o: bad reloc address 0x0 in section `.pdata'
collect2: ld returned 1 exit status
Everything was compiled using GHC 7.10.2 on Windows 10 64-bit.
I did the following:
ghc -c -no-hs-main Inc.hs -o Inc.o
gcc -O -Wall -I/usr/lib/ghc/include -c inc_main.c
ghc -no-hs-main Inc.o inc_main.o -o simplest
This is just explanation of what's going on, see @Hakala's answer for the solution.
The problem is that on Windows file names are case insensitive.
When you are executing
$ ghc -no-hs-main inc.c Inc -o simplest
GHC calls GCC to compile inc.c
into object file inc.o
. But on Windows it also overwrites Inc.o
generated by ghc -c Inc.hs
. So, it is actually the same as executing
$ ghc -no-hs-main inc.c inc.o -o simplest
And linking inc.o
twice will obviously result in "multiple definition" error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With