2017-03-23 11 views
10

私は、C++プログラムでHaskell関数をいくつか呼びたいと思っています。HaskellとC++のインタフェース

これを行うために、私は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. librairiesのパスを更新します。
  3. シンボルエラーを避けるために、ghc引数に-fPICを追加してください。

しかし、私は次の出力で終わる:

$ 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 

私が間違っているのかの任意のアイデアを?

ありがとうございました!

EDIT:

はn.m答えによると、私がg ++引数の順序を変更しました。ここでは新しいメイクファイルです:

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 '[email protected]@GLIBC_2.3.3'

thisスレッドによると、私は-lrtを追加しましたが、得た:

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

そうに従ってthisスレッドを追加しました-ldl BOUNTY私はこの仕事をするために管理し、実際にこれを必要とすることはできませんので、私は評判の私の低量の大部分を費やし恵みを追加している

男:今ではa big mess...

EDITです。

これは学校関連のプロジェクトですが、テーマが「C++で大きなプログラムを作成し、同じプログラムをhaskellに書いてください」と正確に言わなければなりません。

両方のプログラムに共通のグラフィカルインターフェイスを作成することは私の判断であり、コースワークの範囲外です。

さらに、私はインターネット上でこの問題に関する文書が不足していると私の教師は彼がそれをやったことがないと私に言ったので、Haskell Foreign Exportをg ++の構成に組み込んだ答えを構築すると役に立ちます。

ご協力いただきありがとうございます。

+0

あなたは最後-lHSghc-プリム-X.Y.Zパラメータを削除しました。一覧に-lHSghc-prim-x.y.zという別の文字列があるにもかかわらず、リストアを検討してください。 –

+0

完了。新しい出力で投稿を編集しましたが、同じように見えます。ありがとう –

+0

コンパイルコマンドのすべてのオブジェクト/ソースファイルの前にすべてのライブラリがあることに気付きました。**これは間違っていて動作しません**。 [この質問と回答](http://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc)を参照してください。また、リンクラインのライブラリのチェーンの下にHSrtsを移動する必要があると思います。おそらくリストの最後のライブラリでなければなりません。 –

答えて

1

この質問の他のバージョンで私の答えにリンクしようとしましたが、自動的にコメントにすることにしました...将来このスレッドを見つける人は、代わりに完全な答えをペーストしてください。

実際にあなたのファイルにあるのか、それともあなたの質問に入れたバージョンにあるのかはわかりませんが、 "// hello.hs"はコンパイルされません。コメントはハスケルではありません//。

興味深い部分に上とにかく

...

まず、あなたのC++コードにHsFFI.hヘッダファイルをインポートする必要があります。

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

2番目のコマンドでファイルパスがHsFFI.hファイルを含むディレクトリにあります。その後、メイン実行

が出力:

Hello from C++ 
Hello from Haskell 
関連する問題