Ada变体记录是否可以二进制兼容c++联合?
Can an Ada Variant Record be binary compatible to a C++ union?
我正在设计一个通信中间件,用于一个应用程序,该应用程序在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允许)
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- C++typeid模板值转换为联合不可接受的转换
- 如何编写 operator= 用于使用虚拟方法与非平凡成员的匿名联合
- 为什么 std::memmove 中联合的默认非平凡移动构造函数C++?
- 如何将结构/联合数组的成员传递到函数中
- C++:抽象联合和新放置运算符的行为?
- error dllimport 函数的定义不允许在一个特定的联合中,而其他类、结构和联合将按预期导出
- 为什么继承的结构成员在联合中无法访问?
- std::可选实现为联合与字符[]/aligned_storage
- 在向量 C++14(无限制联合)的结构内的联合中创建和存储字符串
- 事件系统:使用类型转换或联合进行继承
- 尝试初始化结构内的联合时出错
- 嵌套在联合中的结构嵌套在 C 中的结构中
- C++浮点数和字节数组的联合问题
- 成员引用基类型 'char' 不是 C++ 中的结构或联合
- 在 c++ 中使用联合时是否可以跳过字节?
- 使用联合时未定义行为的情况
- 结构内部结构的联合 - 混合 C 和 C++
- 访问从联合与另一个成员集复制的联合中的一个成员是否未定义或未指定?
- 联合初始化中的结构