2012-11-24 9 views
14

Ich mache ein kleines Haskell-Spiel in Windows, wo ich jedes Mal antworten möchte, wenn der Benutzer eine Taste drückt. Weil ich unter Windows getCharbehaves strangely verwende, verwende ich FFI, um Zugriff auf getch in conio.h, wie beschrieben here. Der entsprechende Code lautet:cabal FFI-Abhängigkeit

Das funktioniert gut, wenn ich es in Ghci ausführen, oder kompilieren Sie es mit Ghc. Ich möchte auch versuchen, eine Clique Paket aus ihm heraus, so das sich von this Frage, ich gehören die folgenden in meiner Clique Datei:

... 
executable noughts 
    Includes:   conio.h 
    Extra-libraries conio 
... 

Aber wenn ich cabal configure laufen, es sagt mir:

cabal: Missing dependency on a foreign library: 
* Missing C library: conio 

Es macht Sinn, weil in meinem Haskell Plattform-Verzeichnis, unter ...\Haskell Platform\2012.4.0.0\mingw gibt es eine conio.h Datei unter dem include Verzeichnis, aber keine andere conio Datei, um den Objektcode zur Verfügung zu stellen.

Mache ich das richtig, und wenn ja, wie kann ich herausfinden, welche Bibliothek in meine Cabal-Datei aufgenommen werden soll?

+2

Es gibt verschiedene Bibliotheken, die die conio Funktionen. Haben Sie 'Extra-Libraries: crtdll' oder' Extra-Libraries: msvcrt' ausprobiert? Übrigens sollten Sie laut MSDN '_getch' anstelle von' getch' verwenden, aber die Headerdatei könnte das für Sie erledigen. –

+1

Beachten Sie, dass dies nur ghc/ghci in Windows betrifft, und der Lösungscode funktioniert insbesondere in WinHugs nicht, daher müssen Sie nur mit diesem kompilieren, wenn es speziell Windows/ghc ist. – AndrewC

+1

@Tinctorius Ich habe gerade 'Extra-Bibliotheken: msvcrt' und' Extra-Bibliotheken: crtdll' allein und in Kombination ausprobiert. Es hat die Ausgabe von 'cabal build' nicht verändert. Ich fand 'msvcrt.lib' und' crtdll.c' unter meiner Visual Studio-Installation und kopierte sie in meinen Ordner, aber es änderte nichts. – Boris

Antwort

7

Zunächst einmal gibt es nicht immer eine Eins-zu-Eins-Zuordnung zwischen C-Header-Dateien und Bibliotheken. In diesem Fall können die in conio.h deklarierten Funktionen in verschiedenen Laufzeitbibliotheken gefunden werden, wie crtdll (veraltet) oder msvcrt (bevorzugt, denke ich).

Mit der Haskell-Plattform auf Windows, Cabal für diese Bibliotheken in .\mingw\lib aussehen wird (unter dem Verzeichnis Haskell Platform): Wenn Sie für msvcrt fragen, wird es für .\mingw\lib\libmsvcrt.a aussehen. Diese spezielle Bibliothek sollte bereits mit Ihrer Haskell-Plattform geliefert werden. (Wenn Sie auf andere Verzeichnisse mit lib*.a Dateien zeigen möchten, können Sie die Option --extra-lib-dirs von Cabal verwenden.)

Ein kleines Beispiel dafür wäre wie folgt; dies ist Main.hs:

{-# LANGUAGE ForeignFunctionInterface #-} 
import Foreign.C.Types 
foreign import ccall unsafe "conio.h _putch" c_putch :: CInt -> IO() 

main :: IO() 
main = do 
    c_putch . toEnum . fromEnum $ '!' 
    c_putch . toEnum . fromEnum $ '\n' 

Und das something-awesome.cabal wäre:

name:    something-awesome 
version:    0.1.0.0 
build-type:   Simple 
cabal-version:  >=1.8 

executable yay 
    main-is:    Main.hs 
    build-depends:  base ==4.5.* 

    includes:   conio.h 
    extra-libraries:  msvcrt 

Dies sollte funktionieren:

c:\tmp\something-awesome> dir /B 
Main.hs 
something-awesome.cabal 

c:\tmp\something-awesome> cabal configure 
Resolving dependencies... 
Configuring something-awesome-0.1.0.0... 

c:\tmp\something-awesome> cabal build 
Building something-awesome-0.1.0.0... 
Preprocessing executable 'yay' for something-awesome-0.1.0.0... 
[1 of 1] Compiling Main    (Main.hs, dist\build\yay\yay-tmp\Main.o) 
Linking dist\build\yay\yay.exe ... 

c:\tmp\something-awesome> dist\build\yay\yay.exe 
! 
+0

Danke, tolles Beispiel :) – Boris

+1

Für zukünftige Referenz, gibt es irgendwo ich kann nachschlagen, welche Bibliothek bietet eine Funktion? Wie haben Sie herausgefunden, dass '_getch' von msvcrt und crtdll bereitgestellt wird, und dass letzteres veraltet ist? Leichtes Googeln ergab nichts. – Boris

+1

MSDN ist (ein schlechter Versuch) das kanonische Windows-Entwicklungshandbuch, das normalerweise die Header-Datei und die Bibliothek für eine bestimmte Funktion verwendet (Sie können es mit Googles "site:" -Operator suchen). Der Artikel zu [_getch and friends] (http://msdn.microsoft.com/en-us/library/078sfkak%28v=vs.71%29.aspx) erwähnt nur "alle Versionen der C-Laufzeitbibliotheken " unterstütze es. Nachdem ich 'libcrtdll.a' und' libmsvcrt.a' in meinem 'lib'-Verzeichnis gefunden hatte (CRT = C run-time), suchte ich in Google nach dem Unterschied zwischen 'crtdll' und' msvcrt', und fand heraus, dass das erste ist ein Relikt aus der Windows 95-Ära. –

Verwandte Themen