Ada 返回一个胖/粗指针作为输出参数

Ada 返回一个胖/粗指针作为输出参数,ada,Ada,我在创建厚指针时遇到问题。我当前的一组声明如下所示: type Index_Typ is mod 20; -- will be larger in real life type Data_Buffer_Typ is array (Index_Typ range <>) of Integer; --unconstrained array type type Data_Buffer_Ptr is access all Data_Buffer_Typ; -- a thick pointer

我在创建厚指针时遇到问题。我当前的一组声明如下所示:

type Index_Typ is mod 20; -- will be larger in real life
type Data_Buffer_Typ is array (Index_Typ range <>) of Integer; --unconstrained array type
type Data_Buffer_Ptr is access all Data_Buffer_Typ; -- a thick pointer, contains the bounds of array subtype pointed to and address..

Data_Buffer : aliased Data_Buffer_Typ (Index_Typ) := (others => 0); -- this is private
type Result_Typ is (Ok, Overflow, Null_Pointer);

   procedure Retrieve (Index    : in     Index_Typ;
                       Len      : in     Index_Typ;
                       Data_Ptr :    out Data_Buffer_Ptr;
                       Result   :    out Result_Typ) is
   begin
     -- assuming range checks are ok, what goes here ?
   end Retrieve;
并调用
retrieve(2,3,Ptr,Result)如何以指向
数据缓冲区的元素2、3和4的指针结束

注:

  • 是的,我知道分发一个数组片可能会作为 指针,但我们希望显式使用指针,而不是 含蓄地(不是我的选择!)
  • 是的,我做过实验,通常会得到:(
    对象子类型必须静态匹配指定的子类型)错误消息
  • 在可能的情况下,应避免使用新的

    • 这对我来说很有效,尽管我不得不说这很恶心!请注意
      Fat\u Pointer
      中组件的顺序,这与我开始使用的相反,以及这个64位机器上记录的大小(我加入rep子句是为了使顺序明确,没有它也可以正常工作)。此外,我认为您仍在使用
      新的

      with Ada.Text_IO; use Ada.Text_IO;
      with Ada.Unchecked_Conversion;
      with System;
      procedure Fat is
         type Index_Typ is mod 20;
         type Data_Buffer_Typ is array (Index_Typ range <>) of Integer;
         type Data_Buffer_Ptr is access all Data_Buffer_Typ;
         Data_Buffer : aliased Data_Buffer_Typ (Index_Typ) := (others => 0);
         type Result_Typ is (Ok, Overflow, Null_Pointer);
      
         procedure Retrieve (Index    : in     Index_Typ;
                             Len      : in     Index_Typ;
                             Data_Ptr :    out Data_Buffer_Ptr;
                             Result   :    out Result_Typ)
         is
            type Bound is (Lower, Upper);
            type Bounds is array (Bound) of Index_Typ;
            type Bounds_P is access Bounds;
            type Fat_Pointer is record
               The_Data : System.Address;
               The_Bounds : Bounds_P;
            end record;
            for Fat_Pointer use record
               The_Data at 0 range 0 .. 63;
               The_Bounds at 8 range 0 .. 63;
            end record;
            function To_Data_Buffer_Ptr
            is new Ada.Unchecked_Conversion (Fat_Pointer, Data_Buffer_Ptr);
            Answer : constant Fat_Pointer
              := (The_Bounds => new Bounds'(Lower => Index,
                                            Upper => Index + Len - 1),
                  The_Data => Data_Buffer (Index)'Address);
         begin
            Result := Ok;
            Data_Ptr := To_Data_Buffer_Ptr (Answer);
         end Retrieve;
      
         Ptr : Data_Buffer_Ptr := null;
         Result : Result_Typ;
      
      begin
         for J in Data_Buffer'Range loop
            Data_Buffer (J) := Integer (J);
         end loop;
      
         Retrieve (2, 3, Ptr, Result);
      
         for J in Ptr'Range loop
            Put_Line (J'Img & " => " & Ptr (J)'Img);
         end loop;
      end Fat;
      
      带有Ada.Text\u IO;使用Ada.Text\u IO;
      使用Ada.u转换;
      有系统;
      程序脂肪是
      类型索引类型为mod 20;
      type Data\u Buffer\u Typ是整数的数组(索引\u Typ range);
      类型数据缓冲区Ptr是访问所有数据缓冲区类型;
      数据缓冲区:别名数据缓冲区类型(索引类型):=(其他=>0);
      类型结果类型为(Ok,溢出,空指针);
      程序检索(索引:在索引类型中;
      Len:在索引类型中;
      数据\u Ptr:输出数据\u缓冲\u Ptr;
      结果:输出结果(典型)
      是
      类型边界为(下、上);
      类型界限是索引类型的数组(界限);
      类型Bounds_P是访问边界;
      类型Fat\u指针是记录
      _数据:系统地址;
      _界:Bounds_P;
      结束记录;
      对于Fat_指针,请使用记录
      0处的_数据范围为0。。63;
      _的边界为8,范围为0。。63;
      结束记录;
      用于_数据_缓冲区_Ptr的函数
      是新的Ada.Unchecked_转换(Fat_指针、数据_缓冲区_Ptr);
      回答:常量Fat_指针
      :=(_边界=>新边界(下限=>索引,
      上限=>指数+长度-1),
      _Data=>Data_缓冲区(索引)地址);
      开始
      结果:=正常;
      数据\u Ptr:=到\u数据\u缓冲区\u Ptr(应答);
      末端检索;
      Ptr:Data\u Buffer\u Ptr:=null;
      结果:结果类型;
      开始
      对于数据缓冲区范围循环中的J
      数据缓冲区(J):=整数(J);
      端环;
      检索(2,3,Ptr,结果);
      对于Ptr'范围回路中的J
      放线(J'Img&“=>”&Ptr(J)”Img);
      端环;
      末端脂肪;
      
      这对我很有效,尽管我不得不说这很恶心!请注意
      Fat\u Pointer
      中组件的顺序,这与我开始使用的相反,以及这个64位机器上记录的大小(我加入rep子句是为了使顺序明确,没有它也可以正常工作)。此外,我认为您仍在使用
      新的

      with Ada.Text_IO; use Ada.Text_IO;
      with Ada.Unchecked_Conversion;
      with System;
      procedure Fat is
         type Index_Typ is mod 20;
         type Data_Buffer_Typ is array (Index_Typ range <>) of Integer;
         type Data_Buffer_Ptr is access all Data_Buffer_Typ;
         Data_Buffer : aliased Data_Buffer_Typ (Index_Typ) := (others => 0);
         type Result_Typ is (Ok, Overflow, Null_Pointer);
      
         procedure Retrieve (Index    : in     Index_Typ;
                             Len      : in     Index_Typ;
                             Data_Ptr :    out Data_Buffer_Ptr;
                             Result   :    out Result_Typ)
         is
            type Bound is (Lower, Upper);
            type Bounds is array (Bound) of Index_Typ;
            type Bounds_P is access Bounds;
            type Fat_Pointer is record
               The_Data : System.Address;
               The_Bounds : Bounds_P;
            end record;
            for Fat_Pointer use record
               The_Data at 0 range 0 .. 63;
               The_Bounds at 8 range 0 .. 63;
            end record;
            function To_Data_Buffer_Ptr
            is new Ada.Unchecked_Conversion (Fat_Pointer, Data_Buffer_Ptr);
            Answer : constant Fat_Pointer
              := (The_Bounds => new Bounds'(Lower => Index,
                                            Upper => Index + Len - 1),
                  The_Data => Data_Buffer (Index)'Address);
         begin
            Result := Ok;
            Data_Ptr := To_Data_Buffer_Ptr (Answer);
         end Retrieve;
      
         Ptr : Data_Buffer_Ptr := null;
         Result : Result_Typ;
      
      begin
         for J in Data_Buffer'Range loop
            Data_Buffer (J) := Integer (J);
         end loop;
      
         Retrieve (2, 3, Ptr, Result);
      
         for J in Ptr'Range loop
            Put_Line (J'Img & " => " & Ptr (J)'Img);
         end loop;
      end Fat;
      
      带有Ada.Text\u IO;使用Ada.Text\u IO;
      使用Ada.u转换;
      有系统;
      程序脂肪是
      类型索引类型为mod 20;
      type Data\u Buffer\u Typ是整数的数组(索引\u Typ range);
      类型数据缓冲区Ptr是访问所有数据缓冲区类型;
      数据缓冲区:别名数据缓冲区类型(索引类型):=(其他=>0);
      类型结果类型为(Ok,溢出,空指针);
      程序检索(索引:在索引类型中;
      Len:在索引类型中;
      数据\u Ptr:输出数据\u缓冲\u Ptr;
      结果:输出结果(典型)
      是
      类型边界为(下、上);
      类型界限是索引类型的数组(界限);
      类型Bounds_P是访问边界;
      类型Fat\u指针是记录
      _数据:系统地址;
      _界:Bounds_P;
      结束记录;
      对于Fat_指针,请使用记录
      0处的_数据范围为0。。63;
      _的边界为8,范围为0。。63;
      结束记录;
      用于_数据_缓冲区_Ptr的函数
      是新的Ada.Unchecked_转换(Fat_指针、数据_缓冲区_Ptr);
      回答:常量Fat_指针
      :=(_边界=>新边界(下限=>索引,
      上限=>指数+长度-1),
      _Data=>Data_缓冲区(索引)地址);
      开始
      结果:=正常;
      数据\u Ptr:=到\u数据\u缓冲区\u Ptr(应答);
      末端检索;
      Ptr:Data\u Buffer\u Ptr:=null;
      结果:结果类型;
      开始
      对于数据缓冲区范围循环中的J
      数据缓冲区(J):=整数(J);
      端环;
      检索(2,3,Ptr,结果);
      对于Ptr'范围回路中的J
      放线(J'Img&“=>”&Ptr(J)”Img);
      端环;
      末端脂肪;
      
      (a)如果必须使用后缀表示名称指定类型,为什么不使用
      \u type
      ?或者只是
      \u T
      ?(b) 您没有向我们显示
      结果类型
      (c)都是
      数据Ptr
      结果
      真的
      输出
      参数?@SimonWright(a)公司编码标准。(b) 结果类型是一个枚举。不太相关,只是指定操作是否成功或为什么不成功(缓冲区类型错误溢出结束)。(c) 是&是。@SimonWright-in(c)你是说
      in-out
      可能更合适吗?@SimonWright-我猜他们的标准是由一个超级粉丝写的。;-)re:(c)-不,我认为数据可能是输入,结果可能是输出。(a)如果必须使用后缀表示名称指定类型,为什么不使用
      \u type
      ?或者只是
      \u T
      ?(b) 您没有向我们显示
      结果类型
      (c)都是
      数据Ptr
      结果
      真的
      输出
      参数?@SimonWright(a)公司编码标准。(b) 结果类型是一个枚举。不太相关,只是指定操作是否成功或为什么不成功(缓冲区类型错误溢出结束)。(c) 是&是。@SimonWright-in(c)你是说
      in-out
      可能更合适吗@