2017-03-23 2 views
10

C++ 프로그램에서 하스켈 함수를 호출하고 싶습니다.하스켈과 C++ 인터페이스하기

이렇게하려면 these 지침을 적용하고 코드와 시스템에 적응시켜야합니다.

  • 하여 Main.cpp
  • 공유 헤더와 CPP 파일
  • 메이크
  • CPP/
    • 일부 CPP와 헤더 파일 : 나는 순간이 무엇

      는 다음과

  • 하스켈/
    • hello.hs

만들기 파일은 다음과 같은 : 내가 무슨 짓을

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 

내가 잘못 뭐하는 거지의 어떤 생각을?

감사합니다.

편집 :

는 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 

그러나 다른 오류 발생 : this 스레드에 따르면, 내가 -lrt을 추가했지만 가지고

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

을 :

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

두 번째 명령의 파일 경로는 HsFFI.h 파일이 들어있는 디렉토리입니다. 주요 실행

다음 출력 :

Hello from C++ 
Hello from Haskell 
관련 문제