2017-02-13 265 views
0

I have also asked this question @ the Lazarus forums, here接口技術倍頻和拉撒路/ FreePascal的與T加工

我試圖通過T加工與倍頻溝通,但我似乎並沒有能夠從中讀取任何字節。附件是主表格的單元;一個完整的演示應用程序可以從我的帖子下的論壇中以zip的形式獲得。

unit Unit1; 

{$mode objfpc}{$H+} 

interface 

uses 
    Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, Process; 

type 

    { TForm1 } 

    TForm1 = class(TForm) 
    Button1: TButton; 
    Button2: TButton; 
    procedure Button1Click(Sender: TObject); 
    procedure Button2Click(Sender: TObject); 
    private 
    { private declarations } 
    public 
    { public declarations } 
    end; 

var 
    Form1: TForm1; 
    POctave: TProcess; 

implementation 

{$R *.lfm} 

{ TForm1 } 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    if (not POctave.Running) then 
    begin 
    POctave.Executable := 'C:\Octave\Octave-4.2.0\bin\octave-cli.exe'; 
    POctave.Parameters.Add('--no-gui'); 
    POctave.Options := [poUsePipes]; 
    WriteLn('-- Executing octave --'); 
    POctave.Execute; 
    end; 

end; 

procedure TForm1.Button2Click(Sender: TObject); 
var 
    command: string; 
    Buffer: string; 
    BytesAvailable: DWord; 
    BytesRead: longint; 
    NoMoreOutput: boolean; 
begin 
    command := 'pwd' + #10; 
    if (POctave.Running) then 
    POctave.Input.Write(command, Length(command)); 

    if (POctave.Running) then 
    begin 
    BytesAvailable := POctave.Output.NumBytesAvailable; 
    BytesRead := 0; 
    while BytesAvailable > 0 do 
    begin 
     SetLength(Buffer, BytesAvailable); 
     BytesRead := POctave.OutPut.Read(Buffer[1], BytesAvailable); 
     WriteLn(Buffer); 
     BytesAvailable := POctave.Output.NumBytesAvailable; 
     NoMoreOutput := False; 
    end; 
    end; 
end; 

initialization 
    POctave := TProcess.Create(nil); 

finalization 
    POctave.Free; 

end. 

我已經添加了睡眠例程,並將'pwd'命令的返回值更改爲#1310,但都沒有成功。

procedure TForm1.Button2Click(Sender: TObject); 
var 
    command: ansistring; 
    Buffer: string; 
    BytesAvailable: DWord; 
    BytesRead: longint; 
    NoMoreOutput: boolean; 
begin 
    command := 'pwd'#13#10; 
    if (POctave.Running) then 
    POctave.Input.Write(command, Length(command)); 
    Sleep(100); 

    if (POctave.Running) then 
begin 
    Sleep(100); 
    BytesAvailable := POctave.Output.NumBytesAvailable; 
    BytesRead := 0; 
    while BytesAvailable > 0 do 
    begin 
     Sleep(100); 
     SetLength(Buffer, BytesAvailable); 
     BytesRead := POctave.OutPut.Read(Buffer[1], BytesAvailable); 
     WriteLn(Buffer); 
     BytesAvailable := POctave.Output.NumBytesAvailable; 
     NoMoreOutput := False; 
    end; 
    end; 
end; 
+0

當沒有可用的字節和八度不是最快的程序時,您立即中止。 –

+0

不幸的是,我試圖增加睡眠的例程,以允許延遲沒有成功。 – trayres

+0

你能跑'八度--eval 1 + 1'嗎? POctave.Parameters.Add( ' - EVAL'); POctave.Parameters.Add( '1 + 1');順便說一句:你真的想要歸檔什麼?控制八度通過管道? – Andy

回答

1

的問題是,我在呼喚這一行:

POctave.Input.Write(command, Length(command)); 

,而不是這個!

POctave.Input.Write(command[1], Length(command)); 

改變這種情況(將延遲後,這是絕對關鍵的等待對於結果,但我的錯誤更基礎。)

記住:Pascal字符串不是C str英格斯。哎呀...

它的工作!現在我可以發送命令到八度並通過管道檢索結果。 :)

+0

請勿使用睡眠(...)。相反,將poWaitOnExit添加到TProcess的選項中(請參閱http://wiki.freepascal.org/Executing_External_Programs#TProcess) –

+0

實際上,我將要將一些相當大的矩陣轉儲出Octave;如果我使用poWaitOnExit並且緩衝區填滿了,它可能導致死鎖。 – trayres