所以我将以下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_t
,uint16_t
,uint32_t
&之间变化。 uint64_t
,取决于(运行时)参数。这意味着当它在C代码中被读取为(例如)uint16_t数组时,数字将以0,0,4,0,8,0,...而不是预期的0的顺序出现, 4,8,...当uint32_t
被“分割”成2个不同的数字时。
Ada没有近似依赖类型的东西,因此我无法动态创建数组类型。我不确定我怎么能很好地解决这个问题,可能与制作一个Unsigned_8和bithifting数组有关呢?
答案 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;