从C传递结构到Ada [英] Passing structure from C to Ada
问题描述
我需要在Ada绑定应用程序中将结构从C传递到Ada。因此,我在Ada和C中都声明了结构,以便两个源端都可以解密结构组成。
I need to pass a structure from C to Ada in an Ada binding application. Thus, I have declared the structure in both Ada and C so that both the source sides can decipher the structure composition.
在C中,
typedef struct {
int Status_Code;
int Error_Code;
} Edit_Result_Type;
在Ada,
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时,我想知道:
When I am passing the structure from C to Ada through call by reference, I wanted to know:
-
如果我声明结构的全部访问矢量类型,可以吗(如上所述-
Edit_Result_Rec_Type_Ptr
),并将其直接用作Ada函数中的形式参数。例如:
Is it ok if I declare an "access all" vector type for the structure (as done above -
Edit_Result_Rec_Type_Ptr
) in Ada and use it directly as a formal parameter in Ada function. For 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;
这种方法是否致命?我知道是的,只是想深入了解如何!
Is this approach FATAL? I know it is, just wanted to know "how" in depth!
还有其他(更好)的通过引用传递呼叫的方法吗?我相信我可以将其作为 System.Address参数传递,并在Ada函数内部的本地向量中进行未经检查的转换到 Edit_Result_Rec_Type_Ptr
中成员?这种方法有致命的危险吗?
Any other (better) approaches for passing through call by reference? I believe I can pass it as a "System.Address" parameter and do an "unchecked conversion" into Edit_Result_Rec_Type_Ptr
in a local vector inside the Ada function and then read/write record members? Does this approach has any fatalities?
推荐答案
在与Ada和C交互时,您应该真的阅读RM,附件 B.3 ,它表示:
When interfacing Ada and C, you should really read the RM, Annex B.3, which says:
任何类型的记录类型T的Ada参数,除了约定类型C_Pass_By_Copy的in参数外,作为at *参数传递给C函数,其中t是与Ada类型T相对应的C结构。。 p>
An Ada parameter of a record type T, of any mode, other than an in parameter of a type of convention C_Pass_By_Copy, is passed as a t* argument to a C function, where t is the C struct corresponding to the Ada type T.
因此,在您的过程中,只需执行以下操作即可:
So, in your procedure, just do:
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)
(or use the aspect, if Ada 2012)
话虽如此,您不应该在记录定义中使用Integer,Interfaces.C.int才是可行的方法:
That being said, you shouldn't use Integer in your record definition, Interfaces.C.int is the way to go:
type Edit_Result_Rec_Type is
record
Status : Interfaces.C.int;
Error_Code : Interfaces.C.int;
end record;
将与您平台上的C int匹配(假设您的C编译器与Ada编译器兼容)
which will match the C int on your platform (assuming your C compiler is compatible with the Ada compiler)
关于您的问题:
-
那可以,但是为什么要弄乱指针?
That would work, but why mess around with pointers?
不,那是行不通的,Ada中的访问类型(和访问值)不是地址。将 System.Address
转换为访问值需要 System.Address_To_Access_Conversions
,但是,为什么还要弄乱指针呢? / p>
No, that wouldn't work, access types (and access values) in Ada are not addresses. Converting a System.Address
to an access value requires System.Address_To_Access_Conversions
, but again, why mess around with pointers?
这篇关于从C传递结构到Ada的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!