我正在设计一个用于应用程序的通信中间件,该应用程序在Ada中有一个模块,在C ++中有很多模块,用于传递传递参数(标量值)和结构。该应用程序在MS Windows XP和Windows 7中运行,C ++部分正在MSVC ++ 2008中开发,Ada部分正在使用GPS / GNAT开发。 Ada版本是1995年,但我们正处于编译器迁移(更新版本的GPS / GNAT)的中间,可能会使用更新的Ada规范。
中间件是用C ++编写的,我想使用包含在模块之间传递的所有类型的union类型,因此我不需要为系统上使用的每种类型指定一个put / get函数。
问题是,C ++联盟是否与Ada变体记录二进制兼容?换句话说,如果我将C ++联合传递给Ada代码,它是否能够将其作为Variant记录读取? (反之亦然)
我认为为此可能需要进行一些调整......(例如:C ++联盟不包含描述其内容而Ada变体记录的成员)
答案 0 :(得分:7)
可能。
Ada 2005提供了Unchecked_Union pragma,它允许程序“[指定]给定的区分类型和某个C联合之间的接口对应关系.pragma指定相关类型应该给出一个不留下的表示它的判别空间。“
从我阅读RM部分开始,我们声明一个Ada类型,其中包含定义变体记录所需的判别式,但没有为判别式分配存储空间。我认为这在Ada方面意味着随后不能引用判别式。 (还有其他限制,例如所有字段必须与C兼容,有关详细信息,请参阅RM B.3.3。)
我从来没有使用过这个编译指示,我不禁认为需要进行一些实验才能(希望)与你的系统一起工作。祝你好运!
答案 1 :(得分:5)
是。
Ada与C / C ++ Unions兼容。请参阅here了解如何操作(pdf)特别是第5页显示了如何使用Unions& amp;标签。使用判别式记录应该是相同的。 (警告:它可能不是您正在使用的编译器,但如果您的行为方式不同,我会非常惊讶!)
答案 2 :(得分:3)
正如MSalters所提到的,除非由于某种原因C联盟包含指定变体的字段,否则它将无效。因为C中不需要它,所以它通常不起作用。但是,由于你控制了该C类型的实现,因此可以使其工作。只需确保在联合之前有一个字段,指定正在使用哪个联合。
要使它与C union-bearing结构完全二进制兼容,您可能需要使用简单的Ada记录类型以及记录表示子句,以确保字段在同一位置布局C编译器恰好放了它们。是的,这确实使您容易受到C编译器更改的影响,从而导致布局更改。您可以尝试使用C代码中的位域来防止这种情况,但它们的功能不足以真正解决Ada记录rep子句的问题。这是我们更喜欢将Ada用于低级别工作的原因之一。
我应该提一下,当我上次检查时,Windows版本的Gnat与VisualStudio二进制文件不是链接器兼容的。我知道让这两个编译器协同工作的唯一方法是将整个接口放在DLL中。否则,您可能需要使用GCC来构建C ++系统,或者使用其他一些Ada编译器,例如ObjectAda。
答案 3 :(得分:2)
没有。正如您所说,Ada变体记录包含标记字段。 C联盟没有那个。 (至少在MSVC ++和GCC中没有 - 它是ISO C允许的。)