连接Haskell和C ++

时间:2017-03-23 12:56:21

标签: c++ haskell g++ ghc

我想在c ++程序中调用一些Haskell函数。

为此,我申请了these  说明并将其改编为我的代码和系统。

目前我所拥有的是:

  • Main.cpp
  • 共享标头和cpp文件
  • 生成文件
  • CPP /
    • 一些cpp和头文件
  • 哈斯克尔/
    • hello.hs

make文件如下:

CPP_SOURCES = main.cpp textures.cpp cpp/game.cpp \
cpp/piece.cpp cpp/factories.cpp cpp/utils.cpp
HASKELL_SOURCES = haskell/hello.hs

all: main; ./main

main: $(CPP_SOURCES) HaskellPart.o; g++ \
    -lsfml-graphics \
    -lsfml-window \
    -lsfml-system \
    -I/usr/lib/ghc/include \
    -liconv \
    -I/usr/lib/ghc/ghc-8.0.1/include \
    -L/usr/lib/ghc/ghc-8.0.1 \
    -L/usr/lib/ghc/rts \
    -lHSrts \
    -L/usr/lib/ghc/base-4.9.0.0 \
    -lHSbase-4.9.0.0 \
    -L/usr/lib/ghc/ghc-prim-0.5.0.0 \
    -lHSghc-prim-0.5.0.0 \
    -L/usr/lib/ghc/integer-gmp-1.0.0.1 \
    -lHSinteger-gmp-1.0.0.1 \
    -lHSghc-prim-0.5.0.0 \
    -fno-stack-protector \
    -Wall \
    -o main $(CPP_SOURCES) haskell/hello.o

HaskellPart.o: $(HASKELL_SOURCES); ghc -fforce-recomp -fPIC $(HASKELL_SOURCES)

clean: ; rm -rf main && rm -rf haskell/*.o && \
rm -rf haskell/*.hi && rm -rf haskell/*_stub.h

我所做的是:

  1. 添加-I/usr/lib/ghc/include以允许g ++查找HsFFI.h
  2. 更新图书馆路径
  3. -fPIC添加到ghc参数以避免符号错误。
  4. 但是,我最终得到以下输出:

        $ make
    ghc -fforce-recomp -fPIC haskell/hello.hs
    [1 of 1] Compiling Hello            ( haskell/hello.hs, haskell/hello.o )
    g++ \
    -lsfml-graphics \
    -lsfml-window \
    -lsfml-system \
    -I/usr/lib/ghc/include \
     -liconv \
    -L/usr/lib/ghc/rts \
    -lHSrts \
    -L/usr/lib/ghc/base-4.9.0.0 \
    -lHSbase-4.9.0.0 \
    -L/usr/lib/ghc/ghc-prim-0.5.0.0 \
    -lHSghc-prim-0.5.0.0 \
    -L/usr/lib/ghc/integer-gmp-1.0.0.1 \
    -lHSinteger-gmp-1.0.0.1 \
    -lHSghc-prim-0.5.0.0 \
     -fno-stack-protector \
     -Wall \
     -o main main.cpp textures.cpp cpp/game.cpp cpp/piece.cpp cpp/factories.cpp cpp/utils.cpp haskell/hello.o
    /tmp/ccHPRuDY.o: In function `main':
    main.cpp:(.text+0x358): undefined reference to `hs_init'
    main.cpp:(.text+0x375): undefined reference to `hs_exit'
    haskell/hello.o: In function `sRs_info':
    /tmp/ghc9fcb_0/ghc_7.o:(.text+0x2e): undefined reference to `newCAF'
    /tmp/ghc9fcb_0/ghc_7.o:(.text+0x3e): undefined reference to `stg_bh_upd_frame_info'
    /tmp/ghc9fcb_0/ghc_7.o:(.text+0x54): undefined reference to `ghczmprim_GHCziCString_unpackCStringzh_closure'
    /tmp/ghc9fcb_0/ghc_7.o:(.text+0x5d): undefined reference to `stg_ap_n_fast'
    /tmp/ghc9fcb_0/ghc_7.o:(.text+0x96): undefined reference to `newCAF'
    /tmp/ghc9fcb_0/ghc_7.o:(.text+0xa6): undefined reference to `stg_bh_upd_frame_info'
    /tmp/ghc9fcb_0/ghc_7.o:(.text+0xbc): undefined reference to `base_SystemziIO_putStrLn_closure'
    /tmp/ghc9fcb_0/ghc_7.o:(.text+0xc5): undefined reference to `stg_ap_p_fast'
    haskell/hello.o: In function `helloFromHaskell':
    (.text+0xd8): undefined reference to `rts_lock'
    haskell/hello.o: In function `helloFromHaskell':
    (.text+0xee): undefined reference to `base_GHCziTopHandler_runIO_closure'
    haskell/hello.o: In function `helloFromHaskell':
    (.text+0xf9): undefined reference to `rts_apply'
    haskell/hello.o: In function `helloFromHaskell':
    (.text+0x10f): undefined reference to `rts_evalIO'
    haskell/hello.o: In function `helloFromHaskell':
    (.text+0x122): undefined reference to `rts_checkSchedStatus'
    haskell/hello.o: In function `helloFromHaskell':
    (.text+0x12e): undefined reference to `rts_unlock'
    haskell/hello.o: In function `stginit_export_Hello_zdfstableZZC0ZZCmainZZCHelloZZChelloFromHaskell':
    ghc_3.c:(.text+0x144): undefined reference to `foreignExportStablePtr'
    haskell/hello.o: In function `sRs_closure':
    /tmp/ghc9fcb_0/ghc_7.o:(.data+0x40): undefined reference to `stg_IND_STATIC_info'
    haskell/hello.o: In function `rHM_closure':
    /tmp/ghc9fcb_0/ghc_7.o:(.data+0x60): undefined reference to `ghczmprim_GHCziTypes_TrNameS_static_info'
    haskell/hello.o: In function `rI0_closure':
    /tmp/ghc9fcb_0/ghc_7.o:(.data+0x70): undefined reference to `ghczmprim_GHCziTypes_TrNameS_static_info'
    /tmp/ghc9fcb_0/ghc_7.o:(.data+0x80): undefined reference to `ghczmprim_GHCziTypes_Module_static_info'
    haskell/hello.o: In function `SRD_srt':
    /tmp/ghc9fcb_0/ghc_7.o:(.data.rel.ro+0x0): undefined reference to `ghczmprim_GHCziCString_unpackCStringzh_closure'
    /tmp/ghc9fcb_0/ghc_7.o:(.data.rel.ro+0x8): undefined reference to `base_SystemziIO_putStrLn_closure'
    collect2: error: ld returned 1 exit status
    makefile:17: recipe for target 'main' failed
    make: *** [main] Error 1
    

    知道我做错了什么?

    谢谢!

    编辑:

    根据n.m回答,我改变了g ++参数的顺序。这是新的makefile:

    CPP_SOURCES = main.cpp textures.cpp cpp/game.cpp cpp/piece.cpp cpp/factories.cpp cpp/utils.cpp
    HASKELL_SOURCES = haskell/hello.hs
    CFLAGS = -Wall -g -fno-stack-protector
    
    all: main; ./main
    
    main: $(CPP_SOURCES) HaskellPart.o; g++ \
        $(CFLAGS) -o main $(CPP_SOURCES) haskell/hello.o \
        -lsfml-graphics \
        -lsfml-window \
        -lsfml-system \
        -I/usr/lib/ghc/include \
        -liconv \
        -I/usr/lib/ghc/ghc-8.0.1/include \
        -L/usr/lib/ghc/ghc-8.0.1 \
        -L/usr/lib/ghc/base-4.9.0.0 \
        -lHSbase-4.9.0.0 \
        -L/usr/lib/ghc/ghc-prim-0.5.0.0 \
        -lHSghc-prim-0.5.0.0 \
        -L/usr/lib/ghc/integer-gmp-1.0.0.1 \
        -lHSinteger-gmp-1.0.0.1 \
        -lHSghc-prim-0.5.0.0 \
        -L/usr/lib/ghc/rts \
        -lHSrts \
    
    HaskellPart.o: $(HASKELL_SOURCES); ghc -fforce-recomp -fPIC $(HASKELL_SOURCES)
    
    clean: ; rm -rf main && rm -rf haskell/*.o && rm -rf haskell/*.hi && rm -rf haskell/*_stub.h
    

    但它引发了另一个错误:

    /usr/bin/ld: /usr/lib/ghc/rts/libHSrts.a(Itimer.o): undefined reference to symbol 'timer_settime@@GLIBC_2.3.3'

    根据this帖子,我添加了-lrt,但得到了:

    /usr/bin/ld: /usr/lib/ghc/rts/libHSrts.a(Linker.o): undefined reference to symbol 'dlsym@@GLIBC_2.2.5'

    所以根据this帖子,我添加了-ldl,现在它是a big mess...

    编辑:BOUNTY

    伙计我正在增加一笔赏金,因为我无法完成这项工作并真正需要这一点。

    这是针对学校相关的项目,但我必须确切地说这不是作弊,因为主题只说:“用c ++编写一个大程序并在haskell中编写相同的程序”。

    为这两个程序制作一个通用的图形界面是我的决定,不属于课程范围。

    除此之外,我认为在互联网上缺乏关于这个主题的文档,我的老师告诉我他从来没有设法做到这一点,所以用Haskell Foreign Export对g ++的配置做一个构建的答案会很有帮助。 / p>

    感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

尝试链接到我对此问题的其他版本的答案,但它决定自动发表评论...不是特别有帮助,因为将来找到这个帖子的人可能只是认为它没有答案所以我&#39 ;而是粘贴完整的答案。

不确定这是否真的存在于您的文件中,或者它是否只是您在问题中的版本,但是" // hello.hs"不会编译。评论是 - 在Haskell中不是//.

无论如何对有趣的部分......

首先,您需要将HsFFI.h头文件导入C ++代码。

#include <iostream>
#include "Hello_stub.h"
#include <HsFFI.h>

然后在编译文件后使用ghc链接文件。打开命令提示符/终端并导航包含C ++和Haskell文件的目录。然后运行以下命令:

ghc -c -XForeignFunctionInterface -O hello.hs
g++ -c -O main.cpp -I "C:\Program Files\Haskell Platform\7.10.3\lib\include"                         
ghc -no-hs-main hello.o main.o -lstdc++

第二个命令中的文件路径是包含HsFFI.h文件的目录。

运行main然后输出:

Hello from C++
Hello from Haskell
相关问题