从 Ada 程序启动可执行文件并读取结果
Start executable from Ada program and read result
我找到了 个问题,第一个答案包含一些示例代码,演示了如何使用 Ada 代码启动可执行文件。可执行文件的输出被写入标准输出。
为了在 Ada 中进一步 parsing/processing 读取可执行文件的输出(例如逐行),我有哪些选择?
如果您使用 GNAT,那么您可能想看看 GNAT.Expect
包中的 Get_Command_Output
。这是一个例子:
with Ada.Text_IO, GNAT.Expect;
procedure Main is
Command : constant String := "gnat";
Argument_1 : aliased String := "--version";
Input : constant String := "";
Status : aliased Integer := 0;
-- Execute the command and retrieve the output.
Output : String :=
GNAT.Expect.Get_Command_Output
(Command => Command,
Arguments => (1 => Argument_1'Unchecked_Access),
Input => Input,
Status => Status'Access,
Err_To_Out => False);
-- NOTE: Cheating with Unchecked_Access, OK for demo. You may want
-- to properly new and Free these strings (see Argument_List
-- type in package GNAT.OS_Lib).
begin
Ada.Text_IO.Put_Line (Output);
end Main;
执行后的程序returns:
$ ./main
GNAT Community 2019 (20190517-83)
Copyright (C) 1996-2019, Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
可以看出,结果作为单个字符串返回。您将自己进行分线。
更新
针对以下一些评论的更新。
您也可以考虑在 SO 上使用 system
function if you're targeting the Windows platform (see also post)。引用函数参考:
The system function passes command to the command interpreter, which executes the string as an operating-system command.
这与程序 cmd.exe
所做的类似。您可以通过将命令的输出重定向到文件(即使用 >
)来获取命令的输出,然后再将其读回。这是一个例子:
with Ada.Text_IO;
with Ada.Text_IO.Unbounded_IO;
with Ada.Strings.Unbounded;
with Interfaces.C;
with Interfaces.C.Strings;
procedure Main is
use Ada.Strings.Unbounded;
Content : Unbounded_String := Null_Unbounded_String;
begin
-- Execute.
declare
use Interfaces.C;
use Interfaces.C.Strings;
function system (command : chars_ptr) return int
with Import, Convention => C, External_Name => "system";
command : chars_ptr := New_String("gnat --version > gnat_version.out");
result : int := system (command);
begin
-- Check value of result (omitted in this example).
Free(Command);
end;
-- Read.
declare
use Ada.Text_IO;
use Ada.Text_IO.Unbounded_IO;
Fd : File_Type;
begin
Open (Fd, In_File, "./gnat_version.out");
while not End_Of_File (Fd) loop
Content := Content
& Unbounded_String'(Get_Line (Fd))
& ASCII.CR & ASCII.LF; -- Restore the line break removed by Get_Line.
end loop;
Close (fd);
end;
-- Show.
Ada.Text_IO.Unbounded_IO.Put (Content);
end Main;
我找到了
为了在 Ada 中进一步 parsing/processing 读取可执行文件的输出(例如逐行),我有哪些选择?
如果您使用 GNAT,那么您可能想看看 GNAT.Expect
包中的 Get_Command_Output
。这是一个例子:
with Ada.Text_IO, GNAT.Expect;
procedure Main is
Command : constant String := "gnat";
Argument_1 : aliased String := "--version";
Input : constant String := "";
Status : aliased Integer := 0;
-- Execute the command and retrieve the output.
Output : String :=
GNAT.Expect.Get_Command_Output
(Command => Command,
Arguments => (1 => Argument_1'Unchecked_Access),
Input => Input,
Status => Status'Access,
Err_To_Out => False);
-- NOTE: Cheating with Unchecked_Access, OK for demo. You may want
-- to properly new and Free these strings (see Argument_List
-- type in package GNAT.OS_Lib).
begin
Ada.Text_IO.Put_Line (Output);
end Main;
执行后的程序returns:
$ ./main
GNAT Community 2019 (20190517-83)
Copyright (C) 1996-2019, Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
可以看出,结果作为单个字符串返回。您将自己进行分线。
更新
针对以下一些评论的更新。
您也可以考虑在 SO 上使用 system
function if you're targeting the Windows platform (see also
The system function passes command to the command interpreter, which executes the string as an operating-system command.
这与程序 cmd.exe
所做的类似。您可以通过将命令的输出重定向到文件(即使用 >
)来获取命令的输出,然后再将其读回。这是一个例子:
with Ada.Text_IO;
with Ada.Text_IO.Unbounded_IO;
with Ada.Strings.Unbounded;
with Interfaces.C;
with Interfaces.C.Strings;
procedure Main is
use Ada.Strings.Unbounded;
Content : Unbounded_String := Null_Unbounded_String;
begin
-- Execute.
declare
use Interfaces.C;
use Interfaces.C.Strings;
function system (command : chars_ptr) return int
with Import, Convention => C, External_Name => "system";
command : chars_ptr := New_String("gnat --version > gnat_version.out");
result : int := system (command);
begin
-- Check value of result (omitted in this example).
Free(Command);
end;
-- Read.
declare
use Ada.Text_IO;
use Ada.Text_IO.Unbounded_IO;
Fd : File_Type;
begin
Open (Fd, In_File, "./gnat_version.out");
while not End_Of_File (Fd) loop
Content := Content
& Unbounded_String'(Get_Line (Fd))
& ASCII.CR & ASCII.LF; -- Restore the line break removed by Get_Line.
end loop;
Close (fd);
end;
-- Show.
Ada.Text_IO.Unbounded_IO.Put (Content);
end Main;