Кабал FFI зависимость
Я делаю небольшую игру на Haskell в Windows, где я хотел бы отвечать каждый раз, когда пользователь нажимает клавишу. Так как getChar
ведет себя странно в Windows, я использую FFI, чтобы получить доступ к getch
в conio.h
, как описано здесь. Соответствующий код:
foreign import ccall unsafe "conio.h getch" c_getch :: IO CInt
Это прекрасно работает, когда я запускаю его в ghci или компилирую с помощью ghc. Я также хочу попробовать сделать из него пакет cabal, поэтому, исходя из этого вопроса, я включаю в свой файл cabal следующее:
...
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
E сть conio.h
файл под include
каталог, но не другой conio
файл для предоставления объектного кода.
Правильно ли я делаю это, и если да, как я могу узнать, какую библиотеку включить в мой файл кабала?
1 ответ
Во-первых, не всегда существует взаимно-однозначное соответствие между заголовочными файлами C и библиотеками. В этом случае функции объявлены в conio.h
можно найти в различных библиотеках времени выполнения, таких как crtdll
(устарело) или msvcrt
(предпочитаю, наверное).
С помощью платформы Haskell для Windows Cabal будет искать эти библиотеки в .\mingw\lib
(в каталоге вашей платформы Haskell): если вы попросите msvcrt
будет искать .\mingw\lib\libmsvcrt.a
, Эта конкретная библиотека уже должна поставляться с вашей платформой Haskell. (Если вы хотите указать на другие каталоги с lib*.a
файлы, вы можете использовать Cabal's --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
!