从 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 编译的。
我做了以下事情:
- 将 inc.c 重命名为 inc_main.c 因为 C 对象文件 inc.o 可能与 haskell 对象
重叠
- 运行
ghc -c -no-hs-main Inc.hs -o Inc.o
- 通过
gcc -O -Wall -I/usr/lib/ghc/include -c inc_main.c
生成C目标文件
- Link 到带有
ghc -no-hs-main Inc.o inc_main.o -o simplest
的可执行文件
这只是对正在发生的事情的解释,有关解决方案,请参阅@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"错误。
我正在尝试学习如何连接 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 编译的。
我做了以下事情:
- 将 inc.c 重命名为 inc_main.c 因为 C 对象文件 inc.o 可能与 haskell 对象 重叠
- 运行
ghc -c -no-hs-main Inc.hs -o Inc.o
- 通过
gcc -O -Wall -I/usr/lib/ghc/include -c inc_main.c
生成C目标文件
- Link 到带有
ghc -no-hs-main Inc.o inc_main.o -o simplest
的可执行文件
这只是对正在发生的事情的解释,有关解决方案,请参阅@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"错误。