2017-10-05 60 views
2

我正在關注一些FFI教程和示例(herehere),我想知道在使用堆棧時應該改變什麼?外部函數接口(FFI)如何與堆棧一起使用?

在這些示例中,使用gcc -c -o termops.o termops.c將源文件C編譯爲目標文件,並使用ghc --make -main-is FfiEx -o ffi_ex FfiEx.hs termops.o將其包含在gcc編譯中。如何使用堆棧完成相同的操作?

+1

Stack不是正確的組件 - Cabal是。 Stack是一個工具,可以幫助您瞭解如何解決您的依賴關係,而Cabal描述瞭如何構建您的項目。 – Alec

+1

我從來沒有真正直接使用cabal。我直接去使用堆棧。不能堆疊做一切cabal可以? – user668074

+0

不完全。堆棧旨在補充Cabal,而不是替代它。在內部,Stack對Cabal有一定的依賴。 – Alec

回答

5

這是FFI C項目的最小代碼,正如我所能想象的那樣。

$ cd c-proj 
c-proj$ ls 
Main.hs  c-proj.cabal c_file.c 

這些文件的內容:

  • c-proj.cabal:介紹了

    name:   c-proj 
    version:   0.1.0.0 
    cabal-version: >= 1.22 
    build-type:  Simple 
    
    executable main 
        main-is:  Main.hs 
        build-depends: base >= 4.9 
        c-sources:  c_file.c 
    
  • Main.hs:唯一Haskell的源文件

    {-# LANGUAGE ForeignFunctionInterface #-} 
    
    module Main where 
    
    foreign import ccall "plus_ten" plusTen :: Int -> IO Int 
    
    main = do 
        n <- plusTen 2 
        print n 
    
  • c_file.c:C源文件

    #include<stdio.h> 
    
    int plus_ten(int n) { 
        printf("%d + 10\n", n); 
        return n + 10; 
    } 
    

然後,如果你想使用堆棧,可以運行stack init

$ stack init 
<< Shell output snipped >> 
$ stack build 
<< Shell output snipped >> 
$ stack exec main 
2 + 10 
12 
+0

好吧,這就是我正在尋找的。特別是c-sources部分似乎是我所缺少的。後續,有沒有辦法使用目標代碼文件,而不是c源文件? (File.o而不是File.c) – user668074

+1

是的,當然!在'executable main'下,添加以下條目:'extra-lib-dirs:「。」'和'extra-libraries:File.o'。 – Alec

+2

只是挑剔:你可以做得更少。只需將「build-type:Simple」添加到c-proj.cabal的開始部分,即可清除Setup.hs。 – Krom

相關問題