Lazarus
February 09, 2010, 03:13:26 am
Welcome,
Guest
. Please
login
or
register
.
Did you miss your
activation email?
1 Hour
1 Day
1 Week
1 Month
Forever
Login with username, password and session length
News
: Welcome back to Lazarus forum
Home
Forum
Help
Search
Login
Register
Downloads
Daily Snapshots
Wiki
Bugtracker
Developer Blog
Mailing List
IRC channel
Free pascal
Other languages
Useful Wiki Links
FAQ
Project Roadmap
Getting the Source
Screenshots
Search
Advanced search
Articles
Other languages
RC1 of FacturLinEx 2.0
Kelime Ezberim v1.2 (Word Memorizing NOT:Turkish program )
sQueryDNS a tool for Query DNS Servers
New blog about lazarus
Lazarus
>
Forum
>
Using the Lazarus IDE
>
General
>
Interact with octave using TProcess
Pages: [
1
]
« previous
next »
Print
Author
Topic: Interact with octave using TProcess (Read 1496 times)
FangQ
Newbie
Posts: 34
Interact with octave using TProcess
«
on:
May 07, 2009, 12:00:03 am »
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.
Code:
// 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;
Logged
arnoldb
Jr. Member
Posts: 96
Re: Interact with octave using TProcess
«
Reply #1 on:
May 07, 2009, 09:09:48 am »
You are only checking the octave output results very quickly (and one time only).
Try adding a timer to your application with a 5 or 10 ms interval, and put the
Code:
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;
code in the OnTimer Event.
Logged
FangQ
Newbie
Posts: 34
Re: Interact with octave using TProcess
«
Reply #2 on:
May 07, 2009, 03:52:44 pm »
Quote from: arnoldb on May 07, 2009, 09:09:48 am
You are only checking the octave output results very quickly (and one time only).
Try adding a timer to your application with a 5 or 10 ms interval, and put the
thanks for the reply. I tried what you suggested, but got the same result. Only the header copyright info were printed, nothing more.
I attached my test unit with this post, the unit looks like the following. I appreciate for more suggestions.
Code:
unit calloctave;
{$mode objfpc}{$H+}
interface
uses
Classes, Process, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
StdCtrls, ExtCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
mmLog: TMemo;
POctave : TProcess;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
POctave := TProcess.Create(nil);
if(not POctave.Running) then begin
POctave.CommandLine:='octave';
POctave.Options := [poUsePipes];
mmLog.Lines.Add('-- Executing octave --');
POctave.Execute;
Timer1.Enabled:=true;
end
end;
procedure TForm1.Button2Click(Sender: TObject);
var
cmd: String;
begin
cmd:=InputBox('Input','Please type your command','');
cmd:=cmd+'#10';
if(POctave.Running) then
POctave.Input.Write(cmd[1], Length(cmd));
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
if(POctave.Running) then POctave.Terminate(0);
POctave.Free;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
Buffer: string;
BytesAvailable: DWord;
BytesRead:LongInt;
NoMoreOutput: boolean;
begin
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;
initialization
{$I calloctave.lrs}
end.
Logged
FangQ
Newbie
Posts: 34
Re: Interact with octave using TProcess
«
Reply #3 on:
May 07, 2009, 10:09:17 pm »
now I tend to believe the issue is from TProcess.
I wrote a simple perl script to test the interactive read/write from stdin/stdout, as below
Code:
#!/usr/bin/perl
my $b;
print "begin interactive mode\n";
while(1){
$b=<STDIN>;
$b=~s/[\r\n]+$//g;
if($b eq "quit"){
last;
}
print "you typed: $b\n";
}
I saved this file as test.pl, I ran the above program and execute test.pl, pstree shows that the thread test.pl is a sub-process of my gui, however, no matter what I send to this program via TProcess.Input.Write, nothing I can read out of TProcess.Output, even the first "begin interactive mode" message. Isn't that strange?
Running the example code at
https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/examples/process/
gave me the same behavior. Can someone explain?
Logged
Marc
Administrator
Hero Member
Posts: 1948
Re: Interact with octave using TProcess
«
Reply #4 on:
May 11, 2009, 10:21:12 am »
Quote from: FangQ on May 07, 2009, 10:09:17 pm
now I tend to believe the issue is from TProcess.
iirc tprocess cannot execute scripts (it doesn't interepret them, thats something of your shell)
Quote
I saved this file as test.pl, I ran the above program and execute test.pl, pstree shows that the thread test.pl is a sub-process of my gui, ...
do you see "test.pl" as subprocess or do you see "/usr/bin/perl ./test.pl" as subprocess ?
If the first try executing "/usr/bin/perl ./test.pl"
Logged
//--
{$I stdsig.inc}
//-Patches are always welcome at patch (at) dommelstein.net (please put the word "patch" in the subject)
//-I still can't read someones mind
//-Bugs reported on the forum will be forgotten. Use the bug tracker.
Leledumbo
Hero Member
Posts: 858
Re: Interact with octave using TProcess
«
Reply #5 on:
May 11, 2009, 01:00:19 pm »
Wanna try my OctaveGUI? It uses TProcess and input output mechanism similar to what you're trying to achieve.
Logged
FangQ
Newbie
Posts: 34
Re: Interact with octave using TProcess
«
Reply #6 on:
May 11, 2009, 02:56:22 pm »
Quote from: Leledumbo on May 11, 2009, 01:00:19 pm
Wanna try my OctaveGUI? It uses TProcess and input output mechanism similar to what you're trying to achieve.
thank you Leledumbo for sharing your code, it looks very promising. However, I am unable to compile it. Lazarus complains about missing uCmdBox, can you tell me where I can find this unit?
thanks
Logged
FangQ
Newbie
Posts: 34
Re: Interact with octave using TProcess
«
Reply #7 on:
May 11, 2009, 03:19:35 pm »
Quote from: Leledumbo on May 11, 2009, 01:00:19 pm
Wanna try my OctaveGUI? It uses TProcess and input output mechanism similar to what you're trying to achieve.
My stupid. After reading your code, I realized I appended newline incorrectly. After changing cmd+'#10' to cmd+#10, my GUI now works!
thank you so much for showing me your implementation, a working example is really important
Logged
Leledumbo
Hero Member
Posts: 858
Re: Interact with octave using TProcess
«
Reply #8 on:
May 12, 2009, 04:48:41 am »
Quote
Lazarus complains about missing uCmdBox, can you tell me where I can find this unit?
Whoops! Forgot to tell that I'm using TCmdBox component from CmdLine package. Take it from
Lazarus CCR
.
Quote
thank you so much for showing me your implementation, a working example is really important
You're welcome. Glad I can be of help
Logged
Pages: [
1
]
Print
« previous
next »
Jump to:
Please select a destination:
-----------------------------
Anouncements
-----------------------------
=> Team
=> Third party
-----------------------------
Using the Lazarus IDE
-----------------------------
=> Editor
=> Designer
=> Options
=> Debugger
=> General
-----------------------------
Installation
-----------------------------
=> Linux
=> Windows (32/64)
=> Mac OS X
=> PDAs and Smartphones
=> General
-----------------------------
Programming
-----------------------------
=> General
=> LCL
=> Databases
=> Graphics
=> Networking
=> Widgetset
===> Carbon
===> Cocoa
===> GTK
===> QT
===> Win32/64
===> WinCE
===> Other
=> OS
===> Linux
=====> arm
===> OSX
===> Windows
===> Windows CE
===> Other
-----------------------------
Packages
-----------------------------
=> Ported from Delphi/Kylix
=> General
-----------------------------
Suggestions
-----------------------------
=> IDE/CodeTools
=> LCL
-----------------------------
General Issues
-----------------------------
=> Misc
=> Translations
Recent
Lazarus+FPC application b...
by
Zaher
[February 08, 2010, 11:04:17 pm]
Lazarus/MapServer
by
wluis
[February 08, 2010, 11:02:20 pm]
I've a problem with a ser...
by
wluis
[February 08, 2010, 10:57:48 pm]
Lazarus trunk problem - p...
by
tatamata
[February 08, 2010, 09:48:34 pm]
Symbian OS is NOW opensou...
by
SymKeks
[February 08, 2010, 05:33:26 pm]
What is the closest we ha...
by
huwmungous
[February 08, 2010, 04:43:53 pm]
Trouble inserting multipl...
by
huwmungous
[February 08, 2010, 04:40:58 pm]
Lazarus Help Files
by
skalogryz
[February 08, 2010, 03:17:17 pm]
Audorra - Digital 3D audi...
by
scept1c
[February 08, 2010, 02:24:40 pm]
MDI FORMS
by
Ñuño_Martínez
[February 08, 2010, 01:45:20 pm]
TinyPortal v1.0 beta 4 ©
Bloc
Loading...