簡體   English   中英

使用GHCi測試FFI代碼(帶有“外部導入”)

[英]Testing FFI Code (with “foreign import”s) with GHCi

每個人都很好(你當地時間)。

我瀏覽了Real World Haskell關於外部函數接口的章節 ,並在此處進行了一些后續閱讀。 我現在正在嘗試綁定到C函數,我想對一些事情做一些澄清。

以下是相當清楚的:

foreign import ccall unsafe "math.h sin" c_sin :: CDouble -> CDouble

我可以加載這個和在ghci中使用它的代碼,一切都很好。 它甚至可以在emacs的Haskell模式中加載嵌入式ghci。 我覺得這很適合測試。 math是一個系統庫,所以這是直截了當的。

現在來自Real World Haskell的一個例子:

foreign import ccall unsafe "pcre.h pcre_compile" c_pcre_compile :: ...

我故意遺漏了剩下的功能簽名。 現在,我無法在Haskell模式下加載它。 我見過的所有例子都說必須這樣做:

ghci -lpcre

我做了什么,並立即確認正確加載的東西:

GHCi, version 7.6.2: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading object (dynamic) /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../lib/libpcre.so ... done
final link ... done

然后我可以加載我的綁定代碼並測試,但......

_Question 1_我可以從ghci中加載非系統庫,比如pcre嗎? 這將允許我在emacs中測試。

繼續。 當我嘗試將綁定編寫到我自己的 C代碼時,事情變得更加復雜。

foreign import ccall unsafe "myprint.h myprint" c_myprint :: CString -> IO ()

不可否認,這是一個相當無意義的功能。 它需要來自Haskell的ByteString並用C打印。這是一個簡單的測試文件:

{-# LANGUAGE ForeignFunctionInterface #-}
-- printTest.hs

import Foreign
import Foreign.C.Types
import Foreign.C.String

import qualified Data.ByteString.Char8 as B

---

foreign import ccall unsafe "myprint.h myprint" c_myprint :: CString -> IO ()

---

main = B.useAsCString (B.pack "Tempura is great!") c_myprint

我能夠通過這樣做來編譯它:

ghc --make myprint.c printTest.hs

並獲得一個可執行文件,但我根本無法在ghci中加載它。 這嚴重滯后於測試過程。

_Question 2_如何在綁定到我的 C代碼的ghci中加載Haskell代碼? FFI信息的主要來源都沒有任何關於此的說法。 沒有任何擺弄ghci -L可以讓它發揮作用。

請感謝您提供的任何幫助。

ghci將加載任何庫,只要它對您的體系結構有效並且可以位於某個路徑上。 在Windows上,帶有空格的路徑名用於引發問題,我不知道它們是否仍然存在。

要在ghci中加載你自己的代碼,你需要先編譯它,然后告訴ghci加載它的輸出:

mybox$ gcc -c myprint.c
mybox$ ghci Myprint.hs myprint.o

*Main> main
Loading package array-0.4.0.1 ... linking ... done.
Loading package deepseq-1.3.0.1 ... linking ... done.
Loading package bytestring-0.10.0.2 ... linking ... done.
Tempura is great!
*Main>

您還可以將C文件編譯到庫中並將其加載到ghci中,但對於使用目標文件的一個文件來說非常方便。 如果你想創建一個庫,像@Jonke建議的命令應該可行。 在我的系統(OSX)上,

mybox$ gcc -shared -fPIC myprint.c -o libmyprint.dylib
mybox$ ghci -L. -lmyprint Foo.hs

在我的系統上它也可以使用庫文件路徑作為參數,但我不知道它是否可移植。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM