2012-11-24 16 views
14

私は、Windowsでユーザーがキーを押すたびに応答したい小さなHaskellゲームを作っています。 Windows上でgetCharbehaves strangelyがWindows上にあるため、hereと記載されているように、conio.hgetchにFFIを使用してアクセスします。関連するコードは次のとおりです。カタルFFI依存

foreign import ccall unsafe "conio.h getch" c_getch :: IO CInt 

これはghciで実行するかghcでコンパイルすると問題なく動作します。私はまた、そこから秘密結社パッケージを作ってみたいので、this質問から延びる、私は私の秘密結社ファイルに次のものがあります。

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

しかし、私はcabal configureを実行すると、それは私に語った:

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

私のhaskellプラットフォームディレクトリには、...\Haskell Platform\2012.4.0.0\mingwの下にincludeディレクトリの下にconio.hというファイルがありますが、オブジェクトコードを提供するファイルは他にはありません。conioです。

私は正しい方法でこれをやっていますか?もしそうなら、キャブファイルにどのライブラリを含めるべきですか?

+2

conio機能を提供する様々なライブラリがあります。あなたは 'Extra-Libraries:crtdll'または' Extra-Libraries:msvcrt'を試しましたか?ちなみに、MSDNによると、 'getch'の代わりに' _getch'を使うべきですが、ヘッダーファイルがそれを行うかもしれません。 –

+1

これはWindowsのghc/ghciにのみ影響し、特にWinHugsではソリューションコードが機能しないため、特にWindows/ghcの場合のみコンパイルする必要があることに注意してください。 – AndrewC

+1

@Tinctorius私は 'Extra-libraries:msvcrt'と' Extra-libraries:crtdll'だけを組み合わせて試しました。 'cabal build'の出力は変更されませんでした。 Visual Studioのインストールの下で 'msvcrt.lib'と' crtdll.c'を見つけて、それらを私のフォルダにコピーしましたが、何も変わっていませんでした。 – Boris

答えて

7

まず、Cヘッダーファイルとライブラリの間に1対1のマッピングがあるとは限りません。この場合、conio.hで宣言されている関数は、crtdll(旧式)やmsvcrt(好きなことですが)など、さまざまなランタイムライブラリにあります。

Windows上のHaskellプラットフォームでは、Cabalはこれらのライブラリを.\mingw\lib(Haskell Platformディレクトリの下)で探します。msvcrtを求めた場合、.\mingw\lib\libmsvcrt.aが検索されます。この特定のライブラリはHaskell Platformに同梱されているはずです。 (lib*.aファイルで他のディレクトリを指し示す場合は、Cabalの--extra-lib-dirsオプションを使用できます)。

これの小さな例は次のとおりです。これは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' 

そして、これはsomething-awesome.cabal次のようになります。

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 

これは正常に動作する必要があります:

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

ありがとう、すばらしい例:) – Boris

+1

将来参照するために、どこのライブラリが機能を提供するか調べることができますか? '_getch'はmsvcrtとcrtdllによって提供され、後者は非推奨となっていますか?軽いグーグルは何も明らかにしなかった。 – Boris

+1

MSDNは標準的なWindows開発マニュアルです(これは、Googleの 'site:'演算子で検索することができます)。 [_getch and friends](http://msdn.microsoft.com/en-us/library/078sfkak%28v=vs.71%29.aspx)の記事では、「すべてのバージョンのCランタイムライブラリ"それをサポートする。私の 'lib'ディレクトリ(CRT = Cランタイム)で' libcrtdll.a'と 'libmsvcrt.a'を見つけたら、私は' crtdll'と 'msvcrt'の違いをGoogleで検索し、 Windows 95時代からの遺物。 –