Gut (Ihre lokale Tageszeit), alle.Testen von FFI-Code (mit "fremden Import" s) mit GHCi
Ich ging durch Real World Haskell's chapter auf der Fremdfunktionsschnittstelle, und tat einige Follow-up-Lesung here. Ich experimentiere jetzt mit dem Binden von an C-Funktionen, und ich hätte gerne einige Erläuterungen zu einigen Dingen.
Nachstehend ist ziemlich klar:
foreign import ccall unsafe "math.h sin" c_sin :: CDouble -> CDouble
ich dies und Code laden, die es in GHCI verwendet, und alles ist in Ordnung. Es sogar lädt in der eingebetteten Ghci in Emacs Haskell-Modus. Ich finde das großartig zum Testen. math
ist eine Systembibliothek, so dass dies einfach ist.
nun ein Beispiel von Real World Haskell:
foreign import ccall unsafe "pcre.h pcre_compile" c_pcre_compile :: ...
Ich habe absichtlich den Rest der Funktionssignatur weggelassen. Jetzt kann ich das nicht in Haskell-Modus laden. Alle Beispiele, die ich gesehen habe, sagen, dass dies getan werden muss:
ghci -lpcre
Was ich tun, und sofortige Bestätigung, dass die Dinge nicht ordnungsgemäß geladen:
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
dann kann ich laden meine Bindung Code und Test weg, aber ...
_Question 1_ Kann ich non-system Bibliotheken von innerhalb ghci laden, wie pcre? Dies würde erlauben mir innerhalb von Emacs zu testen.
Weitergehen. Dinge werden komplizierter, wenn ich versuche, Bindungen zu meinem eigenen C-Code zu schreiben.
foreign import ccall unsafe "myprint.h myprint" c_myprint :: CString -> IO()
Zugegebenermaßen eine sinnlose Funktion. Es dauert eine ByteString von Haskell und druckt es mit C. Hier ist eine einfache Testdatei ist:
{-# 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
ich diese Lage gewesen, zu kompilieren, indem Sie:
ghc --make myprint.c printTest.hs
Und eine ausführbare Datei, aber Ich konnte es überhaupt nicht in Ghci laden. Dies ist dem Testprozess stark abträglich.
_Question 2_ Was muss ich tun Haskell Code in GHCI zu laden, die zu mein C-Code bindet? Keine der wichtigsten Quellen von FFI-Informationen hatte dazu etwas zu sagen. Keine Menge des Fiedelns mit ghci -L
könnte es zur Arbeit bringen.
Bitte und danke für jede Hilfe, die Sie anbieten können.
Q2, Sie müssen myprint.c als Bibliothek kompilieren, wenn Sie es in Ghci laden möchten. Dies ist c Compiler/os abhängig. – Jonke
Entlang dieser Zeilen (gcc -c-fPIC foo.c -o foo.o und dann gcc -shared -Wl, -Soname, libfoo.so.1 -o libfoo.so.1.0.1 foo.o) oder so ähnlich dass – Jonke