2016-07-13 4 views
1

WXHaskell에 프로그램을 작성하여 작동하는지 확인했습니다. 간단히 말해, GUI 나 명령 행 인터페이스를 통해 프로그램을 사용할 수 있도록 계획했습니다. 나중에 GetOpts 라이브러리를 사용하여 명령 줄 인수 처리를 추가하고 다양한 인수가 의도 한대로 작동하는지 테스트하기 시작했습니다.WxHaskell이 명령 행 arg 기능을 깨뜨림

그러나 일단 프로그램이 명령 행 옵션으로 실행되기 시작하면 프로그램이 실패하기 시작했습니다. 프로그램이 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 

커맨드 라인 인수를 처리하고, (3 간단하여 사용자가 지정한 지능 승산) 계산은 단말기 나 GUI를 통해서 실행된다.

사용자가 "터미널"을 지정하면 문제없이 프로그램이 완료됩니다. 사용자가 args를 지정하지 않으면 계산은 기본적으로 gui 모드에서 실행되며 정상적으로 완료됩니다.

사용자가 "gui"인수를 지정하면 프로그램이 오류 (팝업 창에서)와 충돌합니다 : "예기치 않은 매개 변수 'gui'".

내 arg가 분명히 후속 작업으로 전달되는 이유 또는 더 나은 방법으로이 문제를 방지하는 방법을 알고 있다면 누구나 만족합니다!

+0

그것은 [Graphics.UI.WXCore.Events]에서 함수처럼 보인다 http://hackage.haskell.org/ package/wxcore-0.92.2.0/docs/src/Graphics-UI-WXCore-Events.html) WX의 'start'에 의해 간접적으로 호출되는 'appOnInit'은 argv를 WX 프로세스를 초기화하는 C 코드로 전달합니다. 나는 [여기] (http://hackage.haskell.org/package/wxcore-0.92.2.0/docs/src/Graphics)에 따라 이걸 우회하기 위해 내 '시작', '실행'및 'appOnInit'을 다시 작성했습니다. -UI-WXCore-Events.html)을 사용하여 WX로 전달되는 내용을 제어 할 수 있지만 여전히 작동하지 않습니다.이 함수에 []를 전달해도 WX가 내 argv를 잘못 수신합니다. – Ben

+0

내 직감에서 무엇이 필요할까요? 어떻게 든 argv 배열을 무효화하는 것입니다. _after_ 내 Haskell 프로그램은 args에서 필요한 데이터를 추출했지만 모든 작업을 수행하기 전에는 WX 함수가 호출되기 전에 _ 호출됩니다. argv []에 액세스 할 수있는 외부 C 함수가 NULL에 * argv 포인터를 모두 설정할 수 있다고 가정하고 WX를 전달하여 커맨드 라인 인수가 없다는 생각을하게했습니다. 그러나 이것은 내 지식의 범위를 벗어납니다. . – Ben

답변

4

동일한 문제가 발생했습니다. 내 해결 방법과 같이 명령 줄 인수없이 GUI를 시작하는 withArgs을 사용하는 것이었다 : (

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

고마워, 나는 이것을 시도했지만 여전히 팝업 오류 창이 두 번째 경우에는 인식 할 수없는 'gui'매개 변수에 대해 불평을 받고있다. 위에서 언급했듯이 WX 초기화 코드에서 wxcAppInitializeC 다운 스트림으로 arg가 전달되지 않도록하려면 WX 라이브러리의 'start', 'gui'및 'appOnInit'을 다시 작성했지만 여전히이 오류가 발생합니다. 내 생각 엔 코드가 하류에서 실행되고 있더라도 원래의 argc/argv 메모리 위치에 액세스 할 수 있고 하스켈 코드로 직접 args를 전달하지는 않았지만이를 사용하고있는 것 같습니다. – Ben

+0

@phischu,이 문제가 있었을 때 사용하고 있던 wx Haskell 라이브러리의 버전을 알려주시겠습니까? 현재 0.92.2.0을 사용하고 있습니다. – Ben

+0

wx-0.92.1.0을 사용하고 있습니다. – phischu