从 C 调用 Haskell,出现 "multiple definition of main" 链接器错误

Calling Haskell from C, getting "multiple definition of main" linker error

我正在尝试学习如何连接 Haskell 和 C。首先,我写了 Inc.hs,这是我能想到的最简单的事情:

{-# 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

并编译生成 Inc_stub.h:

ghc -c Inc.hs

工作正常。然后我写了 C 文件,也试图尽可能简单:

#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;
}

试图编译它,得到这个链接器错误:

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

一切都是在 Windows 10 64 位上使用 GHC 7.10.2 编译的。

我做了以下事情:

  1. 将 inc.c 重命名为 inc_main.c 因为 C 对象文件 inc.o 可能与 haskell 对象
  2. 重叠
  3. 运行 ghc -c -no-hs-main Inc.hs -o Inc.o
  4. 通过gcc -O -Wall -I/usr/lib/ghc/include -c inc_main.c
  5. 生成C目标文件
  6. Link 到带有 ghc -no-hs-main Inc.o inc_main.o -o simplest
  7. 的可执行文件

这只是对正在发生的事情的解释,有关解决方案,请参阅@Hakala 的回答。

问题是 Windows 文件名不区分大小写。
当你执行

$ ghc -no-hs-main inc.c Inc -o simplest

GHC 调用 GCC 将 inc.c 编译成目标文件 inc.o。但是在 Windows 上,它也会覆盖由 ghc -c Inc.hs 生成的 Inc.o。所以,其实和执行

是一样的
$ ghc -no-hs-main inc.c inc.o -o simplest

并且链接inc.o两次显然会导致"multiple definition"错误。