I want to interact to an octave or matlab session using pipe functions. I read about TProcess from wiki page (
http://wiki.freepascal.org/Executing_External_Programs), particularly the example at
https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/examples/process/ After some experiments, I wrote the attached code. A button to start an octave process (POctave:TProcess), and then call POctave.Input.Write() to input a user specified command, and POctave.Output.Read() to get the output.
In my tests, the octave process started fine. However, when I sent the command 'version#10' to the pipe, the Output.Read only returned the copyright info printed at the beginning of octave console. This message ended at "type `news'", not even including the "octave:1>" prompt, not mention the output for "version" command.
I tried the same thing for matlab (started with "matlab -nojvm -nodesktop"), I got the same results: Output.Read only returned the copyright info, and no more text available no matter what command I send.
I had a feeling that once octave or matlab started its own console, it somehow does not connect to the stdin/stdout/stderr pipes anymore. I am wondering if anyone can help me out on this? I compiled my code on CentOS5.2, with Lazarus 0.9.26 and fpc 2.2.2. My code are attached below.
thank you in advance.
// start octave process in the background
procedure TForm1.btStartServerClick(Sender: TObject);
begin
POctave := TProcess.Create(nil);
if(not POctave.Running) then begin
POctave.CommandLine:='matlab -nojvm -nodesktop';
POctave.Options := [poUsePipes];
mmLog.Lines.Add('-- Executing octave --');
POctave.Execute;
end
end;
// input a command from user
procedure TForm1.btRunCommandClick(Sender: TObject);
var
cmd: String;
begin
cmd:=InputBox('Input','Please type your command','');
RunOctaveCommand(cmd+'#10');
end;
// and print the output
procedure TForm1.RunOctaveCommand(cmd: String);
var
Buffer: string;
BytesAvailable: DWord;
BytesRead:LongInt;
NoMoreOutput: boolean;
begin
if(POctave.Running) then
POctave.Input.Write(cmd[1], Length(cmd));
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);
mmLog.Text := mmLog.Text + copy(Buffer,1, BytesRead);
BytesAvailable := POctave.Output.NumBytesAvailable;
NoMoreOutput := false;
end;
if BytesRead>0 then
mmLog.SelStart := Length(mmLog.Text);
end;
end;