将结构从C传递到Ada

我需要在Ada绑定应用程序中将结构从C传递给Ada。 因此,我已经在Ada和C中声明了结构,因此两个源侧都可以破译结构组成。

在C中,

typedef struct { int Status_Code; int Error_Code; } Edit_Result_Type; 

在阿达,

 type Edit_Result_Rec_Type is record Status : Integer; Error_Code : Integer; end record; pragma Convention (Convention => C, Entity => Edit_Result_Rec_Type); for Edit_Result_Rec_Type use record Status at 0 range 0 .. 31; Error_Code at 0 range 32 .. 63; end record; type Edit_Result_Rec_Type_Ptr is access all Edit_Result_Rec_Type; 

当我通过参考呼叫将结构从C传递到Ada时,我想知道:

  1. 如果我在Ada中为结构声明一个“access all”矢量类型(如上所述 – Edit_Result_Rec_Type_Ptr )并将其直接用作Ada函数中的forms参数,这样可以Edit_Result_Rec_Type_Ptr ? 对于Eg:

     procedure Process_Data (Edit_Result_Ptr : in out Edit_Result_Rec_Type_Ptr) is begin Edit_Result_Ptr.Status := 1; Edit_Result_Ptr.Error_Code := 0; end Process_Data; 

    这种方法是致命的吗? 我知道,只是想知道“如何”深入!

  2. 通过引用传递调用的任何其他(更好)方法? 我相信我可以将它作为“System.Address”参数传递,并在Ada函数内的本地向量中对Edit_Result_Rec_Type_Ptr进行“未经检查的转换”,然后读/写记录成员? 这种方法有没有死亡?

在连接Ada和C时,你应该真正阅读RM,附件B.3 ,其中说:

任何模式的记录类型T的Ada参数 ,除了约定C_Pass_By_Copy类型的in参数之外, 作为*参数传递给C函数,其中t是对应于Ada类型T的C结构

所以,在你的程序中,只需:

 procedure Process_Data (Edit_Result : in out Edit_Result_Rec_Type) is begin Edit_Result.Status := 1; Edit_Result.Error_Code := 0; end Process_Data; 

 pragma Export(C, Process_Data); 

(或使用方面,如果Ada 2012)

话虽这么说,你不应该在你的记录定义中使用Integer,Interfaces.C.int是要走的路:

 type Edit_Result_Rec_Type is record Status : Interfaces.C.int; Error_Code : Interfaces.C.int; end record; 

它将匹配您平台上的C int(假设您的C编译器与Ada编译器兼容)

至于你的问题:

  1. 那会有用,但为什么乱用指针呢?

  2. 不,这不起作用,Ada中的访问类型(和访问值)不是地址。 将System.Address转换为访问值需要System.Address_To_Access_Conversions ,但同样,为什么要乱用指针?