Ada:包含可变大小数组的打包记录

Squ*_*361 1 arrays ada

我希望创建一个打包记录,可以容纳一个数组,长度从5-50元素不等.是否可以这样做,以便记录可以打包没有浪费的空间?我将在创建记录时知道阵列中有多少元素.

-- the range of the array
type Array_Range_T is Integer range 5 .. 50;

-- the array type
type Array_Type_T is array range (Array_Range_T) of Integer;

-- the record
type My_Record_T (Array_Length : Integer := 5) is
  record
    -- OTHER DATA HERE
    The_Array : Array_Type_T(Array_Length);
  end record;
-- Pack the record
for My_Record_T use
  record
    -- OTHER DATA
    The_Array at 10 range 0 .. Array_Length * 16;
  end record;

for My_Record_T'Size use 80 + (Array_Length * 16);
Run Code Online (Sandbox Code Playgroud)

这显然不会编译,但显示了我想要做的精神.如果可能的话,我想保持阵列的长度不在记录中.

谢谢!

ajb*_*ajb 5

Ada真的没有办法像你要求的那样代表记录.但是,由于您的关注点实际上不在于记录在内存中的表示方式,而在于它如何传输到套接字,您可能不需要担心记录表示条款.

相反,您可以定义自己的Write例程:

procedure Write (Stream : not null access Ada.Streams.Root_Stream_Type'Class;
                 Item   : in My_Record_T);
for My_Record_T'Write use Write;
Run Code Online (Sandbox Code Playgroud)

或者,我相信这将在Ada 2012中有效:

type My_Record_T is record
    ...
end record
with Write => Write;

procedure Write (Stream : not null access Ada.Streams.Root_Stream_Type'Class;
                 Item   : in My_Record_T);
Run Code Online (Sandbox Code Playgroud)

然后身体看起来像

procedure Write (Stream : not null access Ada.Streams.Root_Stream_Type'Class;
                 Item   : in My_Record_T) is
begin
    -- Write out the record components, EXCEPT Array_Length and The_Array.
    T1'Write (Stream, Item.F1);  -- F1 is a record field, T1 is its type
    T2'Write (Stream, Item.F2);  -- F2 is a record field, T2 is its type
    ...

    -- Now write the desired data 
    declare
        Data_To_Write : Array_Type_T (1 .. Item.Array_Length)
            renames Item.The_Array (1 .. Item.Array_Length);
                -- I'm assuming the lower bound is 1, but if not, adjust your code
                -- accordingly
    begin
        Array_Type_T'Write (Stream, Data_To_Write);
            -- Note: using 'Write will write just the data, without any bound 
            -- information, which is what you want.
    end;
end Write;
Run Code Online (Sandbox Code Playgroud)

但是,如果需要打包其他组件,这将无法工作,例如,如果要将字节写入包含一个3位记录组件和一个5位记录组件的套接字.如果这是必要的,我不认为内置'Write属性会为你做那件事; 你可能需要做自己的苦恼,或者你可能会变得棘手并定义一个数组,Stream_Elements并使用一个Address子句或方面来定义一个覆盖其余记录的数组.但我不会使用overlay方法,除非我100%确定套接字另一端的阅读器是一个使用完全相同类型定义的Ada程序.

注意:我没有测试过这个.