使用Cabal从C调用Haskell

时间:2019-01-17 20:23:11

标签: c haskell cabal

我不知道如何构建一个使用外部函数接口调用Haskell的C SDL应用程序,我的主要对象是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

我没有遵循此link中的说明进行操作(适用于OSX,不适用于Linux)。 我正在使用以下方法成功构建Haskell源:

cabal install

但是我无法弄清楚如何以识别Haskell并将其导入C的方式构建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。
  • Cabal版本为1.24.0.2。

2 个答案:

答案 0 :(得分:2)

HsFFI.h位于Haskell安装文件夹中。我正在使用Windows,它位于C:\Program Files\Haskell Platform\8.4.3\lib\include

此外,在构建Haskell模块时,应生成一个.a文件。在我的机器上,它称为HSdll.dll.a。 (为了满足gcc,我必须将其重命名为HSdll.a,但我认为这应该是Windows特定的问题。)

然后以下命令将起作用:

gcc -I"C:\Program Files\Haskell Platform\8.4.3\lib\include" -L. -lHSdll main.c

注意:将-I更改为haskell include文件夹,将-L.更改为.a文件所在的位置。

答案 1 :(得分:1)

这对我有用,但是我使用了GHC而不是阴谋论:

following this example

首先,我编译了我的Haskell库:

mlle.list_of_list_of_elements

然后我使用GHC进行了编译:

ghc -c -O src/haskell/** -outputdir tmp

位置:

  • src / c是我的c源目录。
  • src / haskell是我的Haskell源目录。
  • tmp是我的目标文件文件夹(所有* .o文件)。

尽管我不知道如何使用cabal构建包括c源代码在内的整个项目。