ncurses在解释和编译的Haskell之间有什么区别?

10
我在使用Haskell中的ncurses库中的函数timeoutgetch遇到了奇怪的问题。当我从GHCi或runhaskell中使用它们时,它们按预期工作--getch会等待给定timeout毫秒数后返回,即使没有输入。但是当我使用GHC编译相同的文件时,getch会立即返回。
我尝试了两个针对Haskell的ncurses绑定;hscurses:
import UI.HSCurses.Curses

main = do
  initCurses
  timeout 1000
  c <- getch
  endWin
  print c

以及 ncurses:

import UI.NCurses

main = do
  e <- runCurses $ do
    win <- defaultWindow
    getEvent win $ Just 1000
  print e

两者的行为方式与之前描述的相同奇怪。

我还尝试了C语言中等效的程序:

#include <ncurses.h>

int main()
{
  initscr();
  wtimeout(stdscr,1000);
  int c = getch();
  endwin();
  printf("%d\n", c);
  return 0;
}

这个代码按照预期工作。

所以我的问题是:使用解释的和编译后的Haskell终端时有什么区别?runhaskell和ghci是否修改了一些微妙的终端设置?或者编译后的代码以不同的方式加载库?

添加:

我尝试使用FFI从编译后的Haskell中调用C程序,但它立即返回(这是不正确的)。我认为这意味着问题不在于库,而在于GHC运行时的某个地方。


如果上面展示的代码在编译时确实按照描述的方式运行,那么你应该向库维护者提交一个错误报告。 - didierc
无论是从 REPL 还是使用 runhaskell,它对我都有效。 - didierc
hscurses 版本 1.3.0.2,ghc 6.12.1 - didierc
说实话,我将超时时间修改为5000,以确保代码等待。 - didierc
1
@didierc 是的,它可以在ghci和runhaskell中运行;问题是当被编译后(对我来说)就不起作用了。 - Jan Špaček
显示剩余2条评论
1个回答

1

我尝试了您的代码 - 稍微修改了一个更大的超时值 - 使用runhaskell和以下命令使用ghc:

$ runhaskell so_15305317.hs

$ ghc -packages hscurses -lncurses so_15305317.hs
$ ./a.out

在这两种情况下,我最终获得了预期的行为。您的ghc安装可能存在问题,或者编译时使用的命令包括破坏库行为的参数。
ghc版本为6.12.1,hcurses版本为1.13.0.2,在Debian 6.0.5系统上。

尝试使用相同的命令(只有包名为hscurses),但得到了错误的结果。我的 GHC 版本是 7.4.1,这可能是原因。 - Jan Špaček
啊,是的,名称确实是 hscurses,在我的回答中打错了。 - didierc
所以我猜我们又回到了错误报告的想法。 - didierc
好的,我认为你是对的。我会尝试一些其他的 GHC 版本,找出哪个版本引入了这种行为变化。 - Jan Špaček
2
@honzasp:“我尝试使用FFI从已编译的Haskell调用C程序,但它立即返回(这是不正确的)。“ 这是预期的行为(至少现在是这样)。它在7.2到7.4步骤上发生了变化。请参阅http://hackage.haskell.org/trac/ghc/ticket/7745。 - Daniel Fischer
所以我认为hcurses库的C后端也应该包括SIGVTALRM处理程序,但它可能没有,因此出现了你的问题。 - didierc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接