Can an Ada variant entry be binary compatible with a C ++ union?

I am developing middleware for communication in an application that has a module in Ada and many C ++ modules, which exchanges transmitting parameters (scalar values) and structures. The application works in MS Windows XP and Windows 7, part C ++ is developed in MSVC ++ 2008, part Ada is developed using GPS / GNAT. Ada version is 1995, but we are in the middle of compiler migration (newer version of GPS / GNAT) with the possibility of using the newer Ada specification.

The middle software is written in C ++, and I would like to use a union type containing all the types that are passed between the modules, so I do not need to specify one put / get function for each type that is used in the system.

The question is, are C ++ binary joins compatible with Ada writing options? In other words, if I pass the C ++ union to Ada code, can it read it as a Variant record? (and vice versa)

I think that in order to make this possible, some corrections will be needed ... (For example: C ++ unions do not contain a member that describes its contents, while the entries are Ada variants)

+7
source share
4 answers

Maybe.

Ada 2005 provides an Unchecked_Union pragma that allows the program to "[specify] an interface match between this discriminating type and some C-connection. The pragma indicates that an associated type should be provided with a representation that leaves no room for its discriminant (s)."

From my reading of the RM section, one declares an Ada type with discriminant (s) needed to determine the recording option, but no memory space is allocated for discriminant (s). I believe this is on the side of Ada that the discriminant cannot subsequently be invoked. (There are other restrictions, since all fields must be C-compatible, see RM B.3.3 for more information.)

I have never used this pragma, and I cannot help but think that it will require some experimentation to make (hopefully) work with your system. Good luck

+7
source

Yes.

Ada is compatible with C / C ++ Unions. See here on how to do this (pdf). In particular, it shows how to do this with Unions and tags. It must be the same in order to use discriminant records. (Caution: this is probably not the compiler you are using, but I would be very surprised if you didn’t do the same!)

+5
source

As MSalters mentioned, this will not work unless the C-connection for some reason contains a field indicating the option. Since this is not required in C, this does not often work. However, since you control the implementation of this type of C, you can make it work. Just make sure you have a box in front of the union that indicates which union is used.

To make it fully binary compatible with your C union-bearing construct, you probably need to go with a simple Ada record type along with a proposal to present the record to make sure the fields are in the same places that the C compiler puts them. And yes, that leaves you vulnerable to C compiler changes causing layout changes. You can try to protect yourself from bit fields in your C code, but they are not effective enough to really work out what can be done in the case where records for writing to Ada can be provided. This is one of the reasons we prefer to use Ada for low-level work.

I should mention that the last time I checked, the version of Windows Gnat was not compatible with the linker with VisualStudio binaries. The only way I know to get these two compilers to work together is to install the entire interface in a DLL. Otherwise, you probably need to use GCC to build your C ++ system or use some other Ada compiler, such as ObjectAda .

+3
source

Not. As you yourself claim, the records of the Ada variant contain a tag field. This union does not. (At least not in MSVC ++ and GCC - this is permitted by ISO C.)

+2
source

All Articles