Piping to/from Ada program to a C++ program

孤者浪人 提交于 2019-12-06 05:33:08

You might be more interested in Streams -- http://en.wikibooks.org/wiki/Ada_Programming/Input_Output/Stream_Tutorial

Especially since, if you make a package that binds a stream to a pipe you get free access with Type_Name'Read( stream, object ) & Type_Name'Write( stream, object ).

Code

Compiled on Windows 10 with GNAT GPL 2015

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;

Output

The output will differ from user to user .

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

Ada the language has nothing to say on the subject of pipes; they don't form part of the standard library. I suspect the same is true of C++ and the Boost library (not that I'm a user); pipes are an operating system facility.

Your article 1 contains source which compiles and works with Ada 2005 and Ada 2012 as well as (I expect) Ada 95 - at any rate on Unix systems. Won't that do?

Your article 2 - rather, the Util package found by poking around a bit - says it works on Windows and Unix.

The software available at your article 3 has the great advantage of being maintained!

As for a tutorial - since pipes aren't in the standard you have to use what the people who wrote the particular library you choose have provided. Articles 1 and 3 both contain demonstration programs (I haven't checked article 2). I suspect that's it!

This may be overengineering a little, but there is gnat.sockets if you are allowed to use gnat libraries.

After all a pipe is a simpler version of a socket (or a socket being an expanded version of a pipe), both allow you to transfer data between tasks/processes.

If you want to use Unix pipes in an Ada application, you should consider the POSIX Ada API, as it is a formal standard. One implementation of this is the "FLORIST" library.

The Crimeville language server is an example of how you can use pipes to handle communication between an Ada application and a legacy application with a pipe-friendly interface.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!