【发布时间】: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