Ada变体记录是否可以二进制兼容c++联合?

Can an Ada Variant Record be binary compatible to a C++ union?

本文关键字:c++ 联合 二进制 记录 是否 Ada      更新时间:2023-10-16

我正在设计一个通信中间件,用于一个应用程序,该应用程序在Ada中有一个模块,在c++中有许多模块,可以传递参数(标量值)和结构。本应用程序在Windows XP和Windows 7上运行,c++部分在msvc++ 2008上开发,Ada部分使用GPS/GNAT进行开发。Ada的版本是1995年的,但我们正在进行编译器迁移(更新版本的GPS/GNAT),有可能使用更新的Ada规范。

中间件是用c++编写的,我想使用一个包含在模块之间传递的所有类型的联合类型,这样我就不需要为系统上使用的每种类型指定一个put/get函数。

问题是,c++联合二进制兼容Ada变体记录吗?换句话说,如果我将一个c++联合传递给Ada代码,它将能够读取它作为一个变体记录吗?(反之亦然)

我认为这是可能的一些调整将是必要的…(如。: c++联合不包含描述其内容的成员,而Ada变体记录包含)

可能。

Ada 2005提供了Unchecked_Union pragma,它允许程序"[指定]给定的判别类型和某个C联合之间的接口对应关系"。pragma指定关联的类型应该被赋予一种不为其鉴别符留下空间的表示。"

根据我对RM部分的阅读,声明了一个带有定义变量记录所需的判别符的Ada类型,但是没有为该判别符分配存储空间。我认为这意味着在Ada方面,鉴别不能随后被引用。(还有其他限制,比如所有字段必须与c兼容,参见RM B.3.3了解更多信息。)

我从来没有使用过这个pragma,我不禁认为它需要一些实验才能让它(希望)与您的系统一起工作。好运!

是。

Ada与C/c++ union兼容。请参阅此处了解如何做到这一点(pdf),特别是第5页展示了如何与union &标签。使用Discriminant记录应该是一样的。(警告:这可能不是你正在使用的编译器,但我会非常惊讶,如果你没有表现出同样的方式!)

正如MSalters所提到的,除非C联合由于某种原因包含指定变体的字段,否则它将无法工作。由于这在C中不是必需的,所以它通常不起作用。然而,由于控制该C类型的实现,您可以使其工作。只要确保在联合前面有一个字段,指定正在使用哪个联合。

要使它与C联合结构体完全二进制兼容,您可能需要使用一个简单的Ada记录类型,以及一个记录表示子句,以确保字段放置在C编译器放置它们的相同位置。是的,这确实使您容易受到C编译器更改导致布局更改的影响。您可以尝试在C代码中使用位域来防止这种情况,但它们的功能还不够强大,无法像Ada记录再现子句那样真正地展开内容。这就是我们更喜欢使用Ada进行低级工作的原因之一。

我应该提到,当我上次检查时,Windows版本的Gnat与VisualStudio二进制文件不兼容链接器。我所知道的使这两个编译器一起工作的唯一方法是将整个接口放在DLL中。否则,您可能需要使用GCC来构建您的c++系统,或者使用其他一些Ada编译器,如ObjectAda。

No。如您所述,Ada变体记录包含一个标记字段。而C联盟没有这样的条件。(至少在msvc++和GCC中没有——ISO c允许)