ADA,串行端口,字符串到Stream_element_array

时间:2016-10-14 13:44:27

标签: serial-port ada

        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中的String(1..20)转换为Stream_element_array(1..20)?我已经尝试了明显的答案,而我只是完全卡住了!

根据要求向我投票的人编辑...

1 个答案:

答案 0 :(得分:2)

首先我们需要一个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;

它成功编译并失败并显示错误

  

引发GNAT.SERIAL_COMMUNICATIONS.SERIAL_ERROR:写:端口没有   开

Streams上的一点读数显示了实际问题的答案:

  

如何转换为Stream_element_array(1..20)

是:通常,你不是。 Streams会为你处理这个问题。

分别进行了几处修改:

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

看起来像

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;