Board index » delphi » redirecting


Hi all,

I'm writing a program which is an interface to a commandline utility. I need
a way to receive the program's output in a string.

How can this be done?

I'd prefer not to direct output to a file and then read this as this would
slow things down.




"R. Weijnen" <> wrote:
>Hi all,

>I'm writing a program which is an interface to a commandline utility. I need
>a way to receive the program's output in a string.

>How can this be done?

>I'd prefer not to direct output to a file and then read this as this would
>slow things down.

There are a number of possible solutions.  

One method would be to use the DOS Intra-application Communications
Area, or ICA.  This is a seldom advertised 16 byte block of memory at
physical address 0040:00F0.  Since the ICA is designed to provide memory
based communication between programs, you have to assume that it is very
volatile and take necessary steps to insure that the data being
transferred is valid.  The simplest validation would be to clear (zero)
the ICA before spawning the child process.  If the area is non-zero when
the process ends, you should be able to safely assume it was filled by
the child.  Alternatively the parent could set a signature string
providing the parent's ID and version as part of the information sent
and the child could modify the signature to signal its compatibility,

Another method would be to use a DOS device driver.  If your device
driver supports open, close, read, write, etc., you can simply redirect
the child's output to the device and have the parent read it back.
While this has the overhead of opening and closing a file, the data is a
memory to memory transfer which is one of the things you were looking

I've used a primitive device driver to provide a block of memory to
store common variables and transfer limited amounts of data between DOS
and Win 3.x programs.  The device driver always returned the "real"
address of an internal data area in response to a "read", and simply
returned success and ignored all other commands.  The programs were then
free to use the area of memory internal to the device driver any way I
wanted.  Having more than a 16-byte block of memory that is common to
both DOS and Windows programs are strong advantages for using this
method rather than the ICA.

If the parent is a real mode program that does _not_ swap out of memory,
then it could pass the address of a suitable area within itself for the
result string.  You could pass the address as a command line parameter,
or through the ICA.  If the parent program does use some form of
execswap, then you will have to insure that the memory area is not
swapped.  If the data won't exceed 128 bytes (e.g. String[127]), then
one solution would be to pass the address of the parent's command line
at offset $80 of the parent's program segment prefix.  

The parent program could also obtain a memory segment from DOS and that
segment address could then be passed to the child process.  

If the system has EMS memory, then the parent could obtain and pass the
page handle to the child process.

If the child process doesn't clear the screen when it is done,
you could have the parent read the CRT to retrieve the child's result
string.  In one application I needed to execswap to provide a maximum
amount of memory for a FORTRAN program which always returned a zero
ExitCode.  Before spawning the program, I would writeln(#255) which
would appear as a space on the screen.  Upon return I would use the
current cursor position to retrieve the screen line by line until I had
read 4 non-blank lines, located the #255, reached the top of the screen,
or had identified a successful completion message.  If unable to
identify the completion message, the control program assumed the FORTRAN
program had failed and would add the retrieved lines to its log file.

One of the above should provide an optimal solution to your problem, ;-)

Other Threads