2

我有一个由较小类型组成的记录,总共 16 位大小。

type Type_1 is (val1, val2, val3, val4, val5, val6, val7, val8);
for Type_1 use (val1 => 0, val2 = 1, val3 = 2, val4 => 3
                 val5 => 4, val6 => 5, val7 => 6, val8 => 7);
for Type_1'Size use 3;

type Type_2 is (val1, val2);
for Type_2 use (val1 => 0, val2 = 1);
for Type_2'Size use 1;

etc, etc

type The_Record is record
    element_1 : Type_1;
    element_2 : Type_2;
    element_3 : Type_3;
    element_4 : Type_4;
end record;
for the_Record use record
    element_1 at 0 range 0 .. 2;
    element_2 at 0 range 3 .. 4;
    element_3 at 0 range 5 .. 12;
    element_4 at 0 range 13 .. 15;
end record;
for The_Record'Size use 16;

如何将“The_Record”展平为字节数组或类似的东西?

谢谢!

4

2 回答 2

4

你总是可以使用Unchecked_conversion,但是,这种方法是未经检查的,因此你告诉编译器 (a) 你知道你在做什么,并且 (b) 它不能帮助你[否则它将被命名为 check_conversion]。

您可以进行转换的另一种方法是覆盖,这是我的首选方法(如果它不是简单的类型重命名问题),如果事情发生变化,那么可以根据需要修改转换函数。

-- Subtype-renaming.
Subtype Byte is Interfaces.Unsigned_8;
-- General type for conversion to a collection of bytes.
Type Byte_Array is Array (Positive Range <>) of Byte;
-- Speciffic collection of bytes from The_Record.
Subtype Record_Bytes is Byte_Array(1..The_Record'Size/Byte'Size);

-- Converting record to bytes...
Function Convert( Input : The_Record ) return Record_Bytes is
    Result : Constant Record_Bytes;
    For Result'Address use Input'Address;
    Pragma Import( Convention => Ada, Entity => Result );
begin
    Return Result;
end Convert;

-- Converting bytes to record... in Ada 2012!
Function Convert( Input : Record_Bytes ) return The_Record is
    Result : The_Record with
            Import, Convention => Ada, Address => Input'Address;
begin
    Return Result;
end Convert;

另一种可能更好的方法(如果您正在尝试序列化。我怀疑)这样做是创建读/写函数并覆盖默认值'read'write属性。

于 2013-08-26T19:32:03.823 回答
3

这在一个例子中说明了如何使用的Unchecked Conversion方式:

with Ada.Unchecked_Conversion;
with Ada.Text_Io;

procedure Uc is 

   type The_Record is record
      A : Integer;
      B : Integer;
   end record;

   -- define a byte sized thing...
   type U8 is mod 2**8;
   for U8'Size use 8;

   -- have your array defined according to
   -- the size of the record it needs to hold
   type U8_Record_Array is array (1 .. The_Record'Size / U8'Size) of U8;

   -- instantiate Unchecked_Conversion
   function To_Array is new Ada.Unchecked_Conversion (Source => The_Record,
                                                      Target => U8_Record_Array);
   -- Declare a record and convert it to an array
   R : constant The_Record := (A => 1, B => 2);
   A : constant U8_Record_Array := To_Array (R);

begin
   -- Print the Array As Bytes
   for I in A'Range loop
      Ada.Text_Io.Put (U8'Image (A(I)));
   end loop;

end Uc;

取决于您打算做什么,覆盖和方式Unchecked Conversion都将具有与其相关的优点和缺点:)

于 2013-08-26T20:00:03.990 回答