2

我想将 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 计划,因此如果这不可行,则无需提出替代方案。

谢谢!

4

1 回答 1

3

你不能有没有标签的标签类型,所以它是不可行的。

于 2018-10-04T14:13:05.487 回答