【问题标题】:WxHaskell breaks command line arg functionalityWxHaskell 破坏了命令行参数功能
【发布时间】:2016-11-15 11:00:34
【问题描述】:

我在 WXHaskell 中编写了一个程序,并验证它可以工作。长话短说,我计划通过 GUI 或命令行界面使用该程序。后来我继续使用 GetOpts 库添加命令行参数处理,并开始测试各种参数是否按预期工作。

但是,一旦我开始使用命令行选项运行程序,程序就开始失败:任何时候在 GUI 模式下调用程序(即运行 WXHaskell),程序都会崩溃,并显示有关无法识别的命令行选项的警告(此警告是以 WXwidgets 弹出窗口的形式)。每当程序在终端模式下运行时,所有选项都被正确处理,所以我怀疑运行 WX 计算会导致“ARGV”值被传递给某些 WX 函数,当然,因为这些参数是用于程序主体,它们将无法识别。

我编写了一个小测试用例来重现这种行为(没有 GetOpts)。

import Graphics.UI.WX
import System.Environment (getArgs)

gui = do
  fr <- frame [text := "GUI calculation"]
  t <- staticText fr [text := "Enter a number below"]
  n <- entry fr []
  let foo = do
        v <- read <$> get n text
        set t [text := "Your number * 3 is " ++ show (v * 3 :: Int) ]
  b <- button fr [text := "Calculate", on command := foo]
  set fr [layout := column 3 [widget t, widget n, widget b] ]

terminal = do
  putStrLn "Enter a number"
  v <- read <$> getLine
  putStrLn $ "Your number * 3 is " ++ (show $ v * 3)

main = do
  a <- getArgs
  case a of
    ("terminal"):_ -> terminal
    ("gui"):_ -> start gui
    _ -> start gui

命令行参数被处理,计算(简单地将用户指定的 Int 乘以 3)在终端或通过 gui 运行。

如果用户指定“终端”,程序完成没有问题。如果用户不指定任何参数,则计算默认以 gui 模式运行,并且也正常完成。

如果用户指定“gui”参数,程序会崩溃并出现错误(在弹出窗口中):“Unexpected parameter 'gui'”。

如果有人知道为什么我的参数显然被传递给后续操作,或者更好的是,如何阻止这种情况发生,我会非常高兴!

【问题讨论】:

  • 看起来像Graphics.UI.WXCore.Events'appOnInit'中的函数,它被WX的'start'间接调用,将​​argv传递给初始化WX进程的C代码。根据here,我重写了自己的“开始”、“运行”和“appOnInit”来规避这个问题,以控制传递给 WX 的内容,但它仍然不起作用(甚至将 [] 传递给这个函数仍然会导致 WX 错误地接收我的 argv)
  • 我的直觉告诉我,在我的 Haskell 程序从 args 中提取了它需要的数据之后, 需要以某种方式使 argv 数组无效,但是 before 调用任何 WX 函数,但我不知道如何执行此操作。我假设一个可以访问 argv[] 的外部 C 函数能够将所有 *argv 指针设置为 NULL,从而欺骗 WX 认为没有传递命令行参数,但这有点超出我的知识范围.

标签: haskell command-line-arguments wxwidgets wxhaskell


【解决方案1】:

我也遇到过同样的问题。我的解决方法是使用withArgs 来启动 GUI,而无需像这样的任何命令行参数:

main = do
  a <- getArgs
  case a of
    ("terminal"):_ -> terminal
    ("gui"):_ -> withArgs [] (start gui)
    _ -> withArgs [] (start gui)

【讨论】:

  • 谢谢,我试过了,但我仍然收到一个弹出错误窗口,抱怨第二种情况下无法识别的 'gui' 参数。如上所述,我已经重写了 WX 库的 'start'、'gui' 和 'appOnInit' 以确保在 WX 初始化代码中没有向下游 wxcAppInitializeC 传递任何参数,但仍然出现此错误。我的猜测是,下游运行的任何代码仍然可以访问原始的 argc/argv 内存位置并且正在使用它们,尽管 Haskell 代码没有直接传递任何 args。
  • 你能告诉我,@phischu,当你遇到这个问题时,你使用的是哪个版本的 wx Haskell 库?我目前使用的是 0.92.2.0。
  • 我正在使用 wx-0.92.1.0。
猜你喜欢
  • 2011-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-05
  • 2013-09-05
  • 2018-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多