连接Haskell和C ++ [英] Interfacing Haskell and C++

查看:108
本文介绍了连接Haskell和C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

为了做到这一点,我应用了这些
指令,并将它们改编为我的代码和系统。



什么我现在的情况如下:


  • Main.cpp

  • 共享标题和cpp文件

  • makefile

  • cpp /


    • 一些cpp和头文件
    • li>

  • haskell /


    • 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 \ $ / 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-保护器\
-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参数中,以避免符号错误。

然而,我最终输出如下:

  $ make 
ghc -fforce-recomp -fPIC haskell / hello.hs
编译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-pr im-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:在函数`main'中:
main.cpp :( .text + 0x358):未定义的引用`hs_init'
main.cpp :(。text + 0x375):未定义引用'hs_exit'
haskell / hello.o:函数`sRs_info':
/ tmp / ghc9fcb_0 / ghc_7 .o :(。text + 0x2e):对`newCAF'的未定义引用
/tmp/ghc9fcb_0/ghc_7.o:(.text+0x3e):未定义对`stg_bh_upd_frame_info'的引用
/ tmp / ghc9fcb_0 /ghc_7.o:(.text+0x54):对`ghczmprim_GHCziCString_unpackCStringzh_closure'的未定义引用
/tmp/ghc9fcb_0/ghc_7.o:(.text+0x5d):对`stg_ap_n_fast'的未定义引用
/ tmp /ghc9fcb_0/ghc_7.o:(.text+0x96):对`newCAF'的未定义引用
/tmp/ghc9fcb_0/ghc_7.o:(.text+0xa6):对`stg_bh_upd_frame_info'的未定义引用
/tmp/ghc9fcb_0/ghc_7.o:(.text+0xbc):未定义的引用`base_SystemziIO_putStrLn_closure'
/tmp/ghc9fcb_0/ghc_7.o:(.text+0xc5):对`stg_ap_p_fast'的未定义引用
haskell / hello.o:函数`helloFromHaskell':

haskell / hello.o:在函数`helloFromHaskell'中:
(.text + 0xee):未定义的引用'base_GHCziTopHandler_runIO_closure'
haskell /hello.o:在函数`helloFromHaskell'中:
(.text + 0xf9):未定义引用'rts_apply'
haskell / hello.o:函数`helloFromHaskell':
(。
haskell / hello.o:在函数`helloFromHaskell'中:
(.text + 0x122):未定义引用'rts_checkSchedStatus'
haskell / hello.o:在函数`helloFromHaskell'中:
(.text + 0x12e):对'rts_unlock'的未定义引用
haskell / hello.o:函数`stginit_export_Hello_zdfstableZZC0ZZCmainZZCHelloZZChelloFromHaskell':
ghc_3.c :(。text + 0x144):未定义的引用'foreignE xportStablePtr'
haskell / hello.o:函数`sRs_closure':
/tmp/ghc9fcb_0/ghc_7.o:(.data+0x40):对`stg_IND_STATIC_info'的未定义引用
haskell / hello.o:在函数`rHM_closure'中:
/tmp/ghc9fcb_0/ghc_7.o:(.data+0x60):对`ghczmprim_GHCziTypes_TrNameS_static_info'的未定义引用
haskell / hello.o:在函数`rI0_closure ':
/tmp/ghc9fcb_0/ghc_7.o:(.data+0x70):对`ghczmprim_GHCziTypes_TrNameS_static_info'的未定义引用
/tmp/ghc9fcb_0/ghc_7.o:(.data+0x80):undefined reference到'ghczmprim_GHCziTypes_Module_static_info'
haskell / hello.o:在函数`SRD_srt'中:
/tmp/ghc9fcb_0/ghc_7.o:(.data.rel.ro+0x0):未定义的引用`ghczmprim_GHCziCString_unpackCStringzh_closure'
/tmp/ghc9fcb_0/ghc_7.o:(.data.rel.ro+0x8):对`base_SystemziIO_putStrLn_closure'的未定义引用
collect2:错误:ld返回1退出状态
makefile:17 :目标'主'的配方失败
make:*** [main]错误1

任何想法我做错了什么?



谢谢!



编辑:



根据nm答案, g ++参数的顺序。以下是新的makefile:

  CPP_SOURCES = main.cpp textures.cpp cpp / game.cpp cpp / piece.cpp cpp /工厂.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):对符号'timer_settime @@ GLIBC_2的未定义引用。 3.3'



根据这个线程,我添加了 -lrt 但是得到了:



/ usr / bin / ld:/usr/lib/ghc/rts/libHSrts.a(Linker.o):对符号'dlsym @@ GLIBC_2.2.5'的未定义引用



因此根据这个线程我添加了 -ldl ,现在它是一个大混乱...



编辑:BOUNTY



伙计们,我添加了一笔赏金,因为我的信誉度很低我无法做到这一点,真的需要这样做。



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



为这两个程序创建一个通用图形界面是我的决定,并且超出了课程范围。



除此之外,我认为在互联网上没有关于这个主题的文档,我的老师告诉我他从来没有设法做到这一点,所以用haskell外部输出对g ++进行配置会有帮助。



感谢您的帮助。

解决方案

你的这个问题的其他版本,但它决定自动使它成为一个评论...不是特别有用,因为未来找到这个线程的人可能会认为它没有答案,所以我会粘贴完整的答案。



不知道这是否真的存在于你的文件中,还是只存在于你的问题中,但// hello.hs将不能编译。评论是 - 在Haskell中没有//



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



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

  #include< iostream> 
#includeHello_stub.h
#include< HsFFI.h>

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

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

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



运行main然后输出:

  C ++中的Hello 
Haskell中的Hello


I'd like to call some Haskell functions in a c++ program.

In order to do so, i have applied these instructions and adapted them to my code and system.

What I have for the moment is the following:

  • Main.cpp
  • Shared header and cpp files
  • makefile
  • cpp/
    • some cpp and header files
  • haskell/
    • hello.hs

The make file is the following:

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

What I have done is:

  1. add -I/usr/lib/ghc/include to allow g++ to find HsFFI.h
  2. update the librairies paths
  3. add -fPIC to the ghc arguments to avoid symbol errors.

However, I end up with the following output:

    $ 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

Any idea of what I am doing wrong ?

Thank you!

EDIT :

According to n.m answer, I changed the order of g++ arguments. Here's the new 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

But it raised another error:

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

According to this thread, I added -lrt but got:

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

So according to this thread I added -ldl and now it's a big mess...

EDIT : BOUNTY

Guys I'm adding a bounty spending a large proportion of my low amount of reputation because I can't manage to make this work and really need this.

This is for a school related project but I have to precise that this is not cheating as subject only says: "write a large program in c++ and write the same program in haskell".

Making a common graphical interface for both programs is my decision and is out of the scope of the coursework.

Beside that, I think there a lack of documentation on this subject on internet, my teacher told me he never managed to do it so it would be helpful to have a constructed answer on the configuration of g++ with Haskell Foreign Export.

Thanks you for your help.

解决方案

Tried just linking to my answer on your other version of this question but it decided to automatically make it a comment... Not particularly helpful because people who find this thread in the future might just see it as unanswered so I'll paste the full answer instead.

Not sure whether that's actually in your file or whether it's just in the version you put in your question but "// hello.hs" won't compile. Comments are -- in Haskell not //.

Anyway on to the interesting part...

First you need to import the HsFFI.h header file into your C++ code.

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

Then use ghc to link the files after compiling them. Open a command prompt / terminal and navigate the directory containing your C++ and Haskell files. Then run the following commands:

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++

The filepath in the second command is to the directory containing the HsFFI.h file.

Running main then outputs:

Hello from C++
Hello from Haskell

这篇关于连接Haskell和C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆