Ada:串口,String to Stream_element_array

Ada: Serial port, String to Stream_element_array

        when 'B' |'b' =>
           cons.Put_Line("Enter text - less than 20 chars:   ");
           cons.Get_Line(Item => st,
                         Last => m);

           --buffer_ser'Write(st,m);

           ser.Write(Port   => S_Port,
                     Buffer => buffer_ser);

定义为:

   package cons renames gnat.IO;
   package ser renames gnat.Serial_Communications;

   S_Port : gnat.Serial_Communications.Serial_Port;
   buffer_ser: ada.Streams.Stream_Element_Array(1..20);
   x : Ada.Streams.Stream_Element_Offset;
   m : Integer;
   st : string(1..20) := (others => ASCII.NUL);
   ComPort : GNAT.Serial_Communications.Port_Name(1..5);

基本上,我需要一个非常便携的应用程序来操作基于串行命令覆盖视频流的旧设备。我决定试试 Ada,因为我一直在学习它是为了别的东西。

如何在 Ada 中将字符串 (1..20) 转换为 Stream_element_array(1..20)?我已经尝试了显而易见的答案,但我完全被卡住了!

根据对我投反对票的人的要求进行编辑...

首先我们需要一个 MCVE。

with gnat.IO;
with ada.Streams;
with gnat.Serial_Communications;

procedure MCVE is

   package cons renames gnat.IO;
   package ser renames gnat.Serial_Communications;

   S_Port : gnat.Serial_Communications.Serial_Port;
   buffer_ser: ada.Streams.Stream_Element_Array(1..20);
   x : Ada.Streams.Stream_Element_Offset;
   m : Integer;
   st : string(1..20) := (others => ASCII.NUL);
   ComPort : GNAT.Serial_Communications.Port_Name(1..5);

begin
           cons.Put_Line("Enter text - less than 20 chars:   ");
           cons.Get_Line(Item => st,
                         Last => m);

           --buffer_ser'Write(st,m);

           ser.Write(Port   => S_Port,
                     Buffer => buffer_ser);

end MCVE;

它编译成功并因错误而失败

raised GNAT.SERIAL_COMMUNICATIONS.SERIAL_ERROR : write: port not opened

对 Streams 的一些阅读表明实际问题的答案:

How do I convert to a Stream_element_array(1..20)

是:通常情况下,您不需要。 Streams 会为您处理。

几处修改,分别为:

  • 为 S_Port 设置别名,以便我们可以访问它(以允许可重定向流写入)并删除不必要的中间变量
  • 实际打开串口为Stream
  • 将字符串直接写入流

长得像

S_Port : aliased gnat.Serial_Communications.Serial_Port;
-- buffer_ser: ada.Streams.Stream_Element_Array(1..20);
-- x : Ada.Streams.Stream_Element_Offset;
...
gnat.Serial_Communications.Open(S_Port,ComPort);
String'Write(S_Port'access, st(1..m));
--buffer_ser'Write(st,m);
--ser.Write(Port   => S_Port, Buffer => buffer_ser);

但是在不合适的情况下使用固定长度的字符串是个坏主意。让我们声明字符串的长度合适并进一步简化。这需要 Get_Line 的函数形式,Gnat.IO 包没有提供,所以让我们使用更便携的 Ada.Text_IO 代替。 (并初始化串口名称,实际使用改名后的包...)

当我们完成后,我们有类似的东西

with Ada.Text_IO;
with ada.Streams;
with gnat.Serial_Communications;

procedure MCVE is

   package cons renames Ada.Text_IO;
   package ser renames gnat.Serial_Communications;

   S_Port : aliased ser.Serial_Port;
   ComPort : ser.Port_Name := "COM1";

begin
           ser.Open(S_Port,ComPort);

           cons.Put_Line("Enter text :   ");
           declare
              st : String := cons.Get_Line;
           begin
              String'Write(S_Port'access, st);
           end;
end MCVE;