将结构从C传递到Ada

时间:2016-03-25 21:00:53

标签: 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中结构的矢量类型(如上所述 - Edit_Result_Rec_Type_Ptr),并将其直接用作Ada函数中的形式参数。对于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然后读/写记录成员?这种方法有没有死亡?

1 个答案:

答案 0 :(得分:6)

在连接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,但又一次,为什么要乱用指针?