首页 > 解决方案 > 从 Ada 程序启动可执行文件并读取结果

问题描述

我发现了这个问题,第一个答案包含一些示例代码,演示了如何使用 Ada 代码启动可执行文件。可执行文件的输出被写入标准输出。

为了在 Ada 中进一步解析/处理(例如逐行),我必须读取哪些选项来读取可执行文件的输出?

标签: adagnat

解决方案


如果您使用 GNAT,那么您可能需要查看包Get_Command_Output中的内容。GNAT.Expect这是一个例子:

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;

程序执行后返回:

$ ./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.

可以看出,结果作为单个字符串返回。您将不得不自己拆分线路。


更新

针对以下一些评论的更新。

system如果您的目标是 Windows 平台,您也可以考虑使用该功能(另请参阅 SO 上的这篇文章)。引用函数参考:

system 函数将命令传递给命令解释器,命令解释器将字符串作为操作系统命令执行。

这类似于程序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;

推荐阅读