Вызов Хаскеля из Си с Кабалой
Я не могу понять, как создать приложение C SDL, которое вызывает Haskell с иностранным интерфейсом функций, мой главный находится в C, вот мой файл .cabal:
build-type: Simple
extra-source-files: README.md
cabal-version: >=1.10
library
exposed-modules: AI
other-extensions: ForeignFunctionInterface
build-depends: base >=4.9 && <4.10
hs-source-dirs: src/haskell
default-language: Haskell2010
ghc-options: -O2 -shared -fPIC -dynamic
extra-libraries: HSrts-ghc8.0.2
Я следовал инструкциям в этой ссылке безуспешно (это для OSX, а не для Linux). Я получаю исходный код на Haskell для успешной сборки:
cabal install
Но я не могу понять, как построить код C таким образом, чтобы Haskell был распознан и импортирован в C. Вот пример моих исходников на C и Haskell:
main.c:
#include <stdio.h>
#include "game.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_timer.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_error.h>
#include "HsFFI.h" // include path not recognized
#include "AI_stub.h" // new! edited
int main( int argc, char** argv ) {
hs_init(&argc, &argv);
//HASKELL CALL
int i;
i = fibonacci_hs(42);
printf("Fibonacci: %d\n", i);
//END HASKELL CALL
initializeSdl();
window = createWindow(SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
renderer = createRenderer();
printf("Pre gameLoop\n");
play();
return 0;
}
AI.hs:
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE ForeignFunctionInterface #-}
module AI where
import Foreign.C.Types
fibonacci :: Int -> Int
fibonacci n = fibs !! n
where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
fibonacci_hs :: CInt -> CInt
fibonacci_hs = fromIntegral . fibonacci . fromIntegral
foreign export ccall fibonacci_hs :: CInt -> CInt
PS:
- Я развиваюсь в Ubuntu 18.04.
- Версия GHC - 8.0.2.
- Кабал версия 1.24.0.2.
Ответы
Ответ 1
HsFFI.h
находится в вашей папке установки Haskell. Я использую Windows, и она находится в C:\Program Files\Haskell Platform\8.4.3\lib\include
.
Кроме того, при сборке модуля Haskell должен быть создан файл .a
. На моей машине это называется HSdll.dll.a
. (Я должен переименовать его в HSdll.a
, чтобы удовлетворить требования gcc, но я думаю, что это должно быть HSdll.a
с Windows.)
Тогда будет работать следующая команда:
gcc -I"C:\Program Files\Haskell Platform\8.4.3\lib\include" -L. -LHSdll main.c
Примечание: измените -I
на вашу папку включения в haskell и -L.
к месту, где находится .a
файл.
Ответ 2
Это сработало для меня, но я использовал GHC вместо Cabal:
(следуя этому примеру)
Сначала я скомпилировал свою библиотеку на Haskell:
ghc -c -O src/haskell/** -outputdir tmp
Затем я скомпилировал с GHC:
ghc --make 'sdl2-config --libs --cflags' -optc-O src/c/*.c src/haskell/*.hs -no-hs-main -outputdir tmp -lSDL2_image -o targetLinux/myExecutable
Куда:
- src/c - мой каталог с исходниками.
- src/haskell - это мой исходный каталог на Haskell.
- tmp Моя папка объектных файлов (все файлы *.o).
Хотя я понятия не имею, как построить весь проект, включая c исходные тексты, с Cabal.