2

我以前在 C/C++ 中使用过管道,但我正在努力在一些遗留的 Ada 代码中设置管道......但是我仍处于 Ada 的“学习”阶段,还有很多我还不知道.

话虽如此,我一直在试图弄清楚 Ada 中的管道是如何设置的以及如何使用它们。到目前为止,我只找到了这些文章:

  1. 用于 Unix 子进程和管道的厚 Ada 95 绑定
  2. 包:Util.Pipes
  3. 管道 - ada-util

不要误会我的意思,他们有很多很好的知识,但是 1 是面向 Ada95(我有能力编译到 Ada05),2 只是列出了功能,& 3 几乎没有提供解释。

有人知道 Ada 管道的教程吗?或者更好的是,有人可以举一个简单的例子来说明如何在 Ada 中实现一个简单的管道吗?

我意识到这不是最理想的问题,但我用完了“谷歌组合”......

4

5 回答 5

3

您可能对 Streams 更感兴趣——http: //en.wikibooks.org/wiki/Ada_Programming/Input_Output/Stream_Tutorial

特别是因为,如果您创建一个将流绑定到管道的包,您可以使用 Type_Name'Read(stream, object) 和 Type_Name'Write(stream, object) 免费访问。

于 2013-07-02T20:45:36.627 回答
2

代码

使用 GNAT GPL 2015 在 Windows 10 上编译

with Ada.Text_IO;
with System;
with Interfaces.C;

procedure Main is

   package Pipes is
      type Pipe is private;
      type Get_Result is private;
      function Open_Read (Command : String) return Pipe;
      procedure Close (Stream : Pipe);
      function Get (Stream : Pipe) return Get_Result;
      function End_Of_File (Item : Get_Result) return Boolean;
      function To_Ada (Item : Get_Result) return Character;
   private
      use System;
      use Interfaces.C;
      type Pipe is new Address;
      type Get_Result is new int;
   end;

   package body Pipes is
      function popen (command : char_array; mode : char_array) return Address with Import, Convention => C, External_Name => "popen";
      function pclose (stream : Address) return int with Import, Convention => C, External_Name => "pclose";
      function fgetc (stream : Address) return int with Import, Convention => C, External_Name => "fgetc";
      function Open_Read (Command : String) return Pipe is
         Mode : constant char_array := "r" & nul;
         Result : Address;
      begin
         Result := popen (To_C (Command), Mode);
         if Result = Null_Address then
            raise Program_Error with "popen error";
         end if;
         return Pipe (Result);
      end;
      procedure Close (Stream : Pipe) is
         Result : int;
      begin
         Result := pclose (Address (Stream));
         if Result = -1 then
            raise Program_Error with "pclose error";
         end if;
      end;
      function Get (Stream : Pipe) return Get_Result is
      begin
         return Get_Result (fgetc (Address (Stream)));
      end;
      function End_Of_File (Item : Get_Result) return Boolean is (Item = -1);
      function To_Ada (Item : Get_Result) return Character is (Character'Val (Get_Result'Pos (Item)));
   end;

   procedure Test is
      use Ada.Text_IO;
      use Pipes;
      P : Pipe;
      C : Get_Result;
   begin
      P := Open_Read ("netstat");
      loop
         C := Get (P);
         exit when End_Of_File (C);
         Put (To_Ada (C));
      end loop;
      Close (P);
   end;

begin
   Test;
end;

输出

输出将因用户而异。

Active Connections

  Proto  Local Address          Foreign Address        State
  TCP    192.168.1.140:49698    stackoverflow:https    ESTABLISHED
  TCP    192.168.1.140:49874    stackoverflow:https    ESTABLISHED
  TCP    192.168.1.140:49915    stackoverflow:https    TIME_WAIT
  TCP    192.168.1.140:49916    stackoverflow:https    TIME_WAIT
于 2016-03-13T23:26:18.550 回答
1

这可能有点过度设计,但如果您被允许使用 gnat 库,则有gnat.sockets 。

毕竟管道是套接字的简单版本(或套接字是管道的扩展版本),两者都允许您在任务/进程之间传输数据。

于 2013-07-03T07:22:06.803 回答
1

Ada 语言在管道的主题上无话可说;它们不构成标准库的一部分。我怀疑 C++ 和 Boost 库也是如此(不是我是用户);管道是一种操作系统工具。

您的文章 1包含编译和使用 Ada 2005 和 Ada 2012 以及(我希望)Ada 95 的源代码 - 无论如何在 Unix 系统上。那不行吗?

你的文章 2——更确切地说,是通过四处寻找Util的包——说它适用于 Windows 和 Unix。

您的文章 3 中提供的软件具有维护的巨大优势!

至于教程 - 由于管道不在标准中,您必须使用编写您选择的特定库的人提供的内容。第 1 条和第 3 条都包含演示程序(我没有检查第 2 条)。我怀疑就是这样!

于 2013-07-02T19:54:31.023 回答
0

如果你想在 Ada 应用程序中使用 Unix 管道,你应该考虑 POSIX Ada API,因为它是一个正式的标准。一种实现是“FLORIST”库。

Crimeville语言服务器是一个示例,说明如何使用管道处理 Ada 应用程序和具有管道友好界面的遗留应用程序之间的通信。

于 2013-07-05T21:49:02.190 回答