在Ada-C绑定应用程序中,需要在C和Ada中定义的函数之间传递和读取/写入结构(记录),在C和Ada端声明结构符的最佳方法是什么,以确保正确映射两种语言之间的成员。举个例子,我在C中声明了一个结构(这里没有使用位字段),但是在Ada方面声明相同的结构(在Ada中记录)我还使用了 use 表示子句按位映射,然后使用Convention C pragma。我看到的是Ada没有正确地阅读这个结构,这可能是我认为可能因为成员的错误按位映射。
只是想知道什么是确保在Ada和C方面正确声明相同结构的最佳方法。应该在C侧,使用位字段声明结构,然后使用相同的位方案使用 use 表示子句在Ada端对相同的结构/记录进行十字转换?< / p>
例如C,
/* Position Data Structure */
typedef struct {
float lat;
float lon;
} POSITION_TYPE;
/* Fix Data Structure */
typedef struct {
int32_t fix_id;
char fix_type[20];
char leg_type[7];
char ident[8];
char ident_code[11];
char fix_descriptor[30];
char way_ident[7];
char ref_pt[8];
char ref_pt_code[11];
POSITION_TYPE position;
} FIX_DATA_TYPE;
我在Ada中声明了相同的结构:
-- Position Record --------------------------------------------------------
type Pos_Rec_Type is
record
Lat : C.C_float;
Lon : C.C_float;
end record;
for Pos_Rec_Type use
record
Lat at 0 range 0..31;
Lon at 0 range 32..63;
end record;
pragma Convention (Convention => C, Entity => Pos_Rec_Type);
-- Fix Data Record --------------------------------------------------------
type Fix_Data_Rec_Type is
record
Fix_Id : C.int;
Fix_Type : C.char_array(1..20);
Leg_Type : C.char_array(1..7);
Ident : C.char_array(1..8);
Ident_Code : C.char_array(1..11);
Fix_Desc : C.char_array(1..30);
Way_Ident : C.char_array(1..7);
Ref_Pt : C.char_array(1..8);
Ref_Pt_Code : C.char_array(1..11);
Position : Pos_Rec_Type;
end record;
for Fix_Data_Rec_Type use
record
Fix_Id at 0 range 0..31;
Fix_Type at 0 range 32..191;
Leg_Type at 0 range 192..247;
Ident at 0 range 248..311;
Ident_Code at 0 range 312..399;
Fix_Desc at 0 range 400..639;
Way_Ident at 0 range 640..695;
Ref_Pt at 0 range 696..759;
Ref_Pt_Code at 0 range 760..847;
Position at 0 range 848..911;
end record;
pragma Convention (Convention => C, Entity => Fix_Data_Rec_Type);
但是当我在Ada一侧填充这个结构并将其转移到C函数时,我看到位置记录没有被正确解码。当我禁用 Fix_Data_Rec_Type 的representation子句时,它工作正常。
答案 0 :(得分:3)
如果您使用-gnatR
打印类型的表示信息,您将找到
with rep子句:
for Pos_Rec_Type'Size use 64;
for Pos_Rec_Type'Alignment use 4;
for Pos_Rec_Type use record
Lat at 0 range 0 .. 31;
Lon at 4 range 0 .. 31;
end record;
for Fix_Data_Rec_Type'Object_Size use 928;
for Fix_Data_Rec_Type'Value_Size use 912;
for Fix_Data_Rec_Type'Alignment use 4;
for Fix_Data_Rec_Type use record
Fix_Id at 0 range 0 .. 31;
Fix_Type at 4 range 0 .. 159;
Leg_Type at 24 range 0 .. 55;
Ident at 31 range 0 .. 63;
Ident_Code at 39 range 0 .. 87;
Fix_Desc at 50 range 0 .. 239;
Way_Ident at 80 range 0 .. 55;
Ref_Pt at 87 range 0 .. 63;
Ref_Pt_Code at 95 range 0 .. 87;
Position at 106 range 0 .. 63;
end record;
没有rep子句:
for Pos_Rec_Type'Size use 64;
for Pos_Rec_Type'Alignment use 4;
for Pos_Rec_Type use record
Lat at 0 range 0 .. 31;
Lon at 4 range 0 .. 31;
end record;
for Fix_Data_Rec_Type'Size use 928;
for Fix_Data_Rec_Type'Alignment use 4;
for Fix_Data_Rec_Type use record
Fix_Id at 0 range 0 .. 31;
Fix_Type at 4 range 0 .. 159;
Leg_Type at 24 range 0 .. 55;
Ident at 31 range 0 .. 63;
Ident_Code at 39 range 0 .. 87;
Fix_Desc at 50 range 0 .. 239;
Way_Ident at 80 range 0 .. 55;
Ref_Pt at 87 range 0 .. 63;
Ref_Pt_Code at 95 range 0 .. 87;
Position at 108 range 0 .. 63;
end record;
使用rep子句,Position
组件实际上未对齐(106不能被4整除)。