我需要在Ada绑定应用程序中将结构从C传递给Ada.因此,我已经在Ada和C中声明了结构,因此两个源侧都可以破译结构组成.
在C中,
typedef struct {
int Status_Code;
int Error_Code;
} Edit_Result_Type;
Run Code Online (Sandbox Code Playgroud)
在阿达,
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;
Run Code Online (Sandbox Code Playgroud)
当我通过参考呼叫将结构从C传递到Ada时,我想知道:
如果我Edit_Result_Rec_Type_Ptr在Ada中为结构声明"全部访问"矢量类型(如上所述 - )并将其直接用作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;
Run Code Online (Sandbox Code Playgroud)
这种做法是致命的吗?我知道它是,只是想知道"如何"深入!
通过引用传递呼叫的任何其他(更好)方法?我相信我可以将它作为"System.Address"参数传递,并Edit_Result_Rec_Type_Ptr在Ada函数内的本地向量中进行"未经检查的转换" ,然后读/写记录成员?这种方法有没有死亡?
在连接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;
Run Code Online (Sandbox Code Playgroud)
和
pragma Export(C, Process_Data);
Run Code Online (Sandbox Code Playgroud)
(或使用方面,如果Ada 2012)
话虽这么说,你不应该在你的记录定义中使用Integer,Interfaces.C.int是要走的路:
type Edit_Result_Rec_Type is
record
Status : Interfaces.C.int;
Error_Code : Interfaces.C.int;
end record;
Run Code Online (Sandbox Code Playgroud)
它将匹配您平台上的C int(假设您的C编译器与Ada编译器兼容)
至于你的问题:
那会有用,但为什么乱用指针呢?
不,这不起作用,Ada中的访问类型(和访问值)不是地址.将a转换System.Address为访问值需要System.Address_To_Access_Conversions,但同样,为什么要乱用指针?
| 归档时间: |
|
| 查看次数: |
1013 次 |
| 最近记录: |