将导入的C指针包装为大小相同的Ada标签类型

时间:2018-10-04 14:00:29

标签: ada gnat ada2012

我想将C结构的内存布局复制为Ada类型,同时将C字段(即指针)包装为标记类型,该类型与指针位于相同的内存位置,以避免额外的内存使用,同时以舒适的Ada方式在点指标信息上使用圆点表示法。这要求标记的Ada字段具有与C指针相同的大小。

一个没有标记类型的示例如下:

with Ada.Text_IO; use Ada.Text_IO;

procedure Tag is

   package P is 

      type Int_Ptr is access all Integer with Convention => C;

      --  This would be in reality a C record
      type Rec is record
         I : Int_Ptr := new Integer'(42);
      end record
        with Convention => C;

      --  This is the field wrapper that would be tagged
      type Wrap_I is record -- Making this tagged breaks it
         I : Int_Ptr;
      end record
        with Convention => C;

      function Image (WI : Wrap_I) return String is
        (WI.I.all'Img);

      --  This is the Ada type corresponding to C Rec
      type Wrap_Rec is record
         I : Wrap_I;
      end record
        with Convention => C;

   end P;

   R : P.Rec;
   W : P.Wrap_Rec with Address => R'Address, Import;

begin   
   Put_Line (P.Image (W.I));  -- Should be 42 if properly overlaid

   --  This is the objective: to use dot notation on C pointed data:
   -- Put_Line (W.I.Image);
end Tag;

现在,目标是对Wrap_I进行标记。一旦我将其标记为这样,GNAT就会警告R和W的大小不同(显然,它会导致运行时标记检查失败)。我不需要调度或除静态调用以外的任何东西,因此从本质上讲,我想知道是否存在一种在不将其标记存储在内存中(仅静态使用)的情况下具有标记类型的方法。

我有一个比较传统的计划B,因此如果这样做不可行,则无需提出其他选择。

谢谢!

1 个答案:

答案 0 :(得分:2)

没有标签就不能有标签类型,所以这是不可能的。