我正在關注一些FFI教程和示例(here和here),我想知道在使用堆棧時應該改變什麼?外部函數接口(FFI)如何與堆棧一起使用?
在這些示例中,使用gcc -c -o termops.o termops.c
將源文件C編譯爲目標文件,並使用ghc --make -main-is FfiEx -o ffi_ex FfiEx.hs termops.o
將其包含在gcc編譯中。如何使用堆棧完成相同的操作?
我正在關注一些FFI教程和示例(here和here),我想知道在使用堆棧時應該改變什麼?外部函數接口(FFI)如何與堆棧一起使用?
在這些示例中,使用gcc -c -o termops.o termops.c
將源文件C編譯爲目標文件,並使用ghc --make -main-is FfiEx -o ffi_ex FfiEx.hs termops.o
將其包含在gcc編譯中。如何使用堆棧完成相同的操作?
這是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
好吧,這就是我正在尋找的。特別是c-sources部分似乎是我所缺少的。後續,有沒有辦法使用目標代碼文件,而不是c源文件? (File.o而不是File.c) – user668074
是的,當然!在'executable main'下,添加以下條目:'extra-lib-dirs:「。」'和'extra-libraries:File.o'。 – Alec
只是挑剔:你可以做得更少。只需將「build-type:Simple」添加到c-proj.cabal的開始部分,即可清除Setup.hs。 – Krom
Stack不是正確的組件 - Cabal是。 Stack是一個工具,可以幫助您瞭解如何解決您的依賴關係,而Cabal描述瞭如何構建您的項目。 – Alec
我從來沒有真正直接使用cabal。我直接去使用堆棧。不能堆疊做一切cabal可以? – user668074
不完全。堆棧旨在補充Cabal,而不是替代它。在內部,Stack對Cabal有一定的依賴。 – Alec