Ada

时间:2017-08-21 15:05:04

标签: c arrays ada ffi

所以我将以下Ada数组声明隐藏在一个包体内,最终传递给一个C函数

declare
    type t_buffer is array (0 .. ARR_SIZE) of Unsigned_32;
    buffer : constant access t_buffer := new t_buffer;
begin

   c_obj.buffer_p := buffer (1)'Address;
   c_obj.buffer_length := Unsigned_64 (buffer'Last);
   for idx in Integer range buffer'Range loop
      buffer (idx) := Unsigned_32 (idx * 4);
   end loop;
end

但是,数组的元素实际上并不总是Unsigned_32 / uint32_t - 它在uint8_tuint16_tuint32_t&之间变化。 uint64_t,取决于(运行时)参数。这意味着当它在C代码中被读取为(例如)uint16_t数组时,数字将以0,0,4,0,8,0,...而不是预期的0的顺序出现, 4,8,...当uint32_t被“分割”成2个不同的数字时。

Ada没有近似依赖类型的东西,因此我无法动态创建数组类型。我不确定我怎么能很好地解决这个问题,可能与制作一个Unsigned_8和bithifting数组有关呢?

1 个答案:

答案 0 :(得分:3)

Ada的工作方式,你必须有四种不同的数组类型。

但是您可以在变体记录中封装数组类型的选择:

package Variant_Records is

   type Word_Sizes is range 8 .. 64
     with Static_Predicate => Word_Sizes in 8 | 16 | 32 | 64;

   type Data_8_Bit  is mod 2 **  8 with Size =>  8;
   type Data_16_Bit is mod 2 ** 16 with Size => 16;
   type Data_32_Bit is mod 2 ** 32 with Size => 32;
   type Data_64_Bit is mod 2 ** 64 with Size => 64;

   type Array_8_Bit  is array (Positive range <>) of Data_8_Bit;
   type Array_16_Bit is array (Positive range <>) of Data_16_Bit;
   type Array_32_Bit is array (Positive range <>) of Data_32_Bit;
   type Array_64_Bit is array (Positive range <>) of Data_64_Bit;

   type Data_Array (Word_Size : Word_Sizes;
                    Length    : Natural) is
      record
         case Word_Size is
            when  8 => Data_8  : Array_8_Bit  (1 .. Length);
            when 16 => Data_16 : Array_16_Bit (1 .. Length);
            when 32 => Data_32 : Array_32_Bit (1 .. Length);
            when 64 => Data_64 : Array_64_Bit (1 .. Length);
         end case;
      end record;

end Variant_Records;

然后是一些用法的例子:

with Variant_Records;

procedure Using_Variant_Records is
   use Variant_Records;

   A : Data_Array (Word_Size =>  8, Length => 16);
   B : Data_Array (Word_Size => 64, Length =>  2);
begin
   for I in A.Data_8'Range loop
      A.Data_8 (I) := 2 * Data_8_Bit (I) + 4;
   end loop;

   for I in B.Data_64'Range loop
      B.Data_64 (I) := Data_64_Bit (8 ** I) + 4;
   end loop;

   declare
      D : Data_Array := B;
   begin
      for E of D.Data_64 loop
         E := E * 8;
      end loop;
   end;
end Using_Variant_Records;
相关问题