2015-10-01 112 views
0

我試圖編寫一個由另一個程序作爲進程啓動的Pascal(Lazarus/FPC)程序。調用者(Arena chess GUI)使用StdIn和StdOut與我的程序對話。Pascal StdIn/StdOut管道

首先,我在我的程序中使用READLN來獲取從GUI和WRITELN發送的文本命令來回復它們。這很好,除了如果READLN必須等待來自GUI的輸入,我的程序將停止執行任何操作。由於我希望程序繼續工作,並且只在命令到達時處理,所以我必須改變它。

所以我改變了代碼使用方法:

... 
var inpStream  : TInputPipeStream; 
... 
inpStream := TInputPipeStream.Create(StdInputHandle); 
... 
if inpStream.NumBytesAvailable > 0 then begin 
    SetLength(s_buffer, inpStream.NumBytesAvailable); 
    inpStream.Read(s_buffer[1], length(s_buffer)); 
end; 
... 

這工作真的很好,因爲它不再停下來讀。但是然後WRITELN停止工作:沒有任何東西被髮送回GUI。我想也許這會有所幫助:

... 
var inpStream  : TInputPipeStream; 
    outStream  : TOutputPipeStream; 
... 
inpStream := TInputPipeStream.Create(StdInputHandle); 
outStream := TOutputPipeStream.Create(StdOutputHandle); 
... 
if inpStream.NumBytesAvailable > 0 then begin 
    SetLength(s_buffer, inpStream.NumBytesAvailable); 
    inpStream.Read(s_buffer[1], length(s_buffer)); 
end; 
... 
outStream.Write(s_buffer, length(s_buffer)); 

但是,這使得它變得更糟,因爲現在它不讀或寫任何東西。那麼,如何在保持StdOut寫入能力的同時在StdIn上有非阻塞的輸入?

回答

0

假設您使用Windows,可能意味着讀取您的輸出的程序不會經常讀取它(它可以讓它大量增加),然後當管道的總大小達到一定的大小(通常爲幾個MB )窗口停止處理。

這是一個新的情況,需要深入研究Windows管道和作業控制。在FPC 3.x TProcess中,一些錯誤得到修復,並且類似(如果stderr沒有經常處理,請參閱intrun命令代碼,管道處理停滯)。

如果接收程序沒有處理標準錯誤,請不要使用它。

0

好吧,這很尷尬!原因是由於程序中的邏輯錯誤,未正確發送對GUI的答覆。感謝您的回答,雖然馬可,是的,我正在使用Windows。所以事實證明:

READLN/WRITELN的作品,但停止的程序,直到進入READLN。

TInputPipeStream/WRITELN在不停止程序的情況下工作,所以解決了我的問題。

TInputStream/TOutputStream似乎不能一起工作,我不知道爲什麼。這是我試圖初始化它們的方式,還是它們應該是排他性的?