Я хотел бы вызвать некоторые функции Haskell в программе на C ++.
Для этого я подал заявку эти
инструкции и адаптировали их к моему коду и системе.
На данный момент у меня есть следующее:
Файл 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
Что я сделал, это:
-I/usr/lib/ghc/include
разрешить g ++ найти HsFFI.h
-fPIC
к аргументам GHC, чтобы избежать ошибок символов.Тем не менее, я получаю следующий вывод:
$ 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 ++. Вот новый make-файл:
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'
В соответствии с этот нить я добавил -lrt
но получил:
/usr/bin/ld: /usr/lib/ghc/rts/libHSrts.a(Linker.o): undefined reference to symbol 'dlsym@@GLIBC_2.2.5'
Так согласно этот нить я добавил -ldl
и теперь это большой беспорядок …
РЕДАКТИРОВАТЬ: BOUNTY
Ребята, я добавляю награду, которая тратит большую часть моей низкой репутации, потому что я не могу сделать эту работу и действительно нуждаюсь в этом.
Это для проекта, связанного со школой, но я должен уточнить, что это не обман, поскольку субъект говорит только: «напиши большую программу на c ++ и напиши ту же самую программу на haskell».
Создание общего графического интерфейса для обеих программ — мое решение и выходит за рамки курсовой работы.
Кроме того, я думаю, что в Интернете не хватает документации по этому предмету, мой учитель сказал мне, что ему так и не удалось это сделать, поэтому было бы полезно получить подробный ответ о конфигурации g ++ с Haskell Foreign Export.
Спасибо вам за вашу помощь.
Попробовал просто дать ссылку на мой ответ на другой версии этого вопроса, но он решил автоматически сделать это комментарием … Не особенно полезно, потому что люди, которые найдут эту ветку в будущем, могут просто увидеть ее как без ответа, поэтому я вставлю полную версию ответь вместо
Не уверен, что это на самом деле в вашем файле или в той версии, которую вы указали в своем вопросе, но «hello.hs» не скомпилируется. Комментарии есть — в Хаскеле нет //.
Во всяком случае, на интересную часть …
Сначала вам нужно импортировать файл заголовка 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.
Запустив основной, затем вывод:
Hello from C++
Hello from Haskell
Других решений пока нет …