Я хотел бы скопировать структуру памяти C struct в тип 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, поэтому нет необходимости предлагать альтернативы, если это невозможно.
Спасибо!