2012-11-24 127 views
14

我在Windows制作小Haskell的游戏,在这里我想给每个用户按下某个键时做出响应。由于getCharbehaves strangely在Windows上,我用FFI获得在conio.h访问getch,如所描述here。相关的代码是:阴谋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下有一个conio.h文件,在include目录下没有其他conio文件提供目标代码。

难道我这个做了正确的方式,如果是这样,我怎么能找到我的阴谋文件,包括库?

+2

有迹象表明,提供conio功能的各种库。你有尝试'额外的图书馆:crtdll'或'额外的图书馆:msvcrt'?顺便说一下,根据MSDN,你应该使用'_getch'而不是'getch',但是头文件可能会为你做。 – 2012-11-24 19:42:29

+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头文件和库之间的一对一的映射。在这种情况下,在conio.h声明的函数可以以各种运行时库中找到,如crtdll(不建议使用)或msvcrt(优选的,我想)。

借助Windows上的Haskell平台,Cabal将在.\mingw\lib(位于您的Haskell Platform目录下)中查找这些库:如果您要求msvcrt,它会查找.\mingw\lib\libmsvcrt.a。这个特定的库应该已经与你的Haskell平台一起发货。 (如果你想指向其他目录与文件lib*.a,您可以用惊天动地的--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开发手册,通常给人的头文件和库使用给定函数(你可以用谷歌的'网站搜索一下:'运营商)。在[_getch和朋友(http://msdn.microsoft.com/en-us/library/078sfkak%28v=vs.71%29.aspx)文章只提到,“在所有C版本的运行时库“支持它。找到'我'lib'目录(CRT = C运行时)libcrtdll.a'和'libmsvcrt.a'后,我再搜索谷歌为crtdll'和'msvcrt''之间的差别,并推断出前者是Windows 95时代的遗迹。 – 2012-11-26 14:47:54