Ada 83 地址到数组的转换

Ada 83 Address to Array Conversion

在我继承的代码中,缓冲区使用其起始地址和长度作为参数传递给过程。此过程代码使用内联汇编语言来处理缓冲区内容。

在使用相同参数的新过程中,我想将缓冲区作为数组引用,但我想使用与现有过程相同的参数及其类型。这样我就不必对原始代码进行侵入式修改,除非使用相同的调用签名,如下所示:

procedure Push_Buffer(
    Source_Address : Address;
    Count          : Natural);

在这种情况下,缓冲区只是一个机器字数组。我想将其称为机器字数组,并且已经具有可以在其他地方使用而没有问题的类型(Word 和 Buffer_Type)。 (无约束类型的对象 Buffer_Type 在使用它们的地方定义了约束。)

我想在我的过程中将地址传递的缓冲区称为数组。我该怎么做?

像这样(适用于 -gnat83,但可能不适用于真正的 Ada83 编译器;我没有可以检查的):

with Text_IO; use Text_IO;
with System;
procedure Push is
   type Integers is array (Positive range <>) of Integer;

   procedure Push_Buffer (Source_Address : System.Address;
                          Count : Natural) is
      Source : Integers (1 .. Count);
      for Source use at Source_Address;
   begin
      for J in Source'Range loop
         Put_Line (Integer'Image (J) & " => " & Integer'Image (Source (J)));
      end loop;
   end Push_Buffer;

begin
   declare
      Data : Integers (1 .. 3) := (4, 5, 6);
   begin
      Push_Buffer (Data'Address, Data'Length);
   end;
end Push;

作为旁注,可能与您的情况无关:如果您指定地址的对象的默认初始化有任何问题(例如,如果它是一个包含访问变量的结构,这些访问变量是默认的-初始化为 null) 您需要通过将声明写为

来抑制初始化
  Source : Integers (1 .. Count);
  pragma Import (Ada, Source);
  for Source use at Source_Address;

(或类似编译器相关的东西;GNAT 说 warning: (Ada 83) pragma "Import" is non-standard)。看到GNAT Reference Manual 8.15, Address Clauses,大概走到一半了。

我会使用无约束数组作为参数,而不是 System.Address。这确保编译器不会传递绑定信息(在 gcc 和 gnat 中也称为 "fat pointers"),并且应该与 pragma import 兼容。

type Unconstrained_Integer_Array is array (Positive) of Integer;
procedure Push_Buffer (Buffer : Unconstrained_Integer_Array;
                       Length : Natural)
is
begin
    for A in 1 .. Length loop
          ...
    end loop;
end Push_Buffer;

我们在 GtkAda 绑定中与 C 接口时使用类似的技巧