【发布时间】:2016-08-06 16:09:04
【问题描述】:
首先,我指定我使用的是 Windows 10 64bit 和 Haskell Platform 8.0.1。
我尝试使用以下代码在 Windows 中使用 Haskell 的 FFI。
import Control.Monad
import Data.Char
import Foreign.C
getCh :: IO Char
getCh = liftM (chr . fromEnum) c_getch
foreign import ccall unsafe "conio.h getch" c_getch :: IO CInt
main :: IO ()
main = getCh >>= \x -> print x
在这之后,我可以用 ghc 很好地编译这个
> ghc Examples.hs
[1 of 1] Compiling Main ( Examples.hs, Examples.o )
Linking Examples.exe ...
它完全运行。
> Examples.exe
'1'
(当我在运行后输入 1)
但是,GHCI 会出现问题。当我将它加载到 ghci 时,我收到了这些消息。
> ghci Examples.hs
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( Examples.hs, interpreted )
Ok, modules loaded: Main.
*Main> main
ByteCodeLink: can't find label
During interactive linking, GHCi couldn't find the following symbol:
getch
This may be due to you not asking GHCi to load extra object files,
archives or DLLs needed by your current session. Restart GHCi, specifying
the missing library using the -L/path/to/object/dir and -lmissinglibname
flags, or simply by naming the relevant files on the GHCi command line.
Alternatively, this link failure might indicate a bug in GHCi.
If you suspect the latter, please send a bug report to:
glasgow-haskell-bugs@haskell.org
*Main>
我尝试加载“缺少的库”,例如“-lmsvcrt”需要使用conio.h,但结果很悲观。
> ghci -lmsvcrt Examples.hs
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( Examples.hs, interpreted )
Ok, modules loaded: Main.
*Main> main
ByteCodeLink: can't find label
During interactive linking, GHCi couldn't find the following symbol:
getch
This may be due to you not asking GHCi to load extra object files,
archives or DLLs needed by your current session. Restart GHCi, specifying
the missing library using the -L/path/to/object/dir and -lmissinglibname
flags, or simply by naming the relevant files on the GHCi command line.
Alternatively, this link failure might indicate a bug in GHCi.
If you suspect the latter, please send a bug report to:
glasgow-haskell-bugs@haskell.org
*Main>
GHCI 可能会加载库,因为当我尝试加载错误的库时,ghci 会打印出错误。
我尝试了其他几种方法,例如使用ghci Examples.hs -fobject-code、ghci -lmsvcrt Examples.hs -fobject-code,甚至
ghci Examples.hs "-luser32" "-lgdi32" "-lwinmm" "-ladvapi32" "-lshell32"
"-lshfolder" "-lwsock32" "-luser32" "-lshell32" "-lmsvcrt" "-lmingw32"
"-lmingwex" "-luser32" "-lmingw32" "-lmingwex" "-lm" "-lwsock32" "-lgdi32" "-lwinmm"
在ghc Examples.hs -v5 中找到。
遗憾的是,我的 main 没有任何用处,我找不到任何其他方法。
附:有没有人知道如何在 Windows 中使用 hSetBuffering(8 年前在ghc ticket #2189 上发布过。不是修复了吗?)
【问题讨论】:
-
我只能告诉你两件无益的事情:1. 在 Linux 中使用
stdio.h getchar可以正常工作,无需指定库;2. 你的方法看起来大致正确。 -
@Eric 在 Linux 中,这种情况下不需要 FFI,因为 hSetBuffering 函数可以正常工作,通过使用该函数,我可以进行 Bufferless Input。但是,这种方法不适用于 Windows。
-
我仅指您尝试与
getChar链接的主要问题。我不能帮你解决缓冲问题。 -
w.r.t ticket #2189,正在进行的工作是慢慢地将 GHC 中的 IO 管理器替换为原生 Windows 管理器。但它很慢,因为没有很多 Windows 维护人员。我目前必须优先处理影响最多人的工单。
标签: windows haskell ffi ghci console-input