Ada to C ++: pass a 64-bit unsigned value

I need to transfer 2 pieces of data from an Ada program to some C ++ code for processing.

  • The data is double.
  • Time - unsigned 64 bits.

I managed to make a procedure in Ada that worked with my C ++ method using Long_Float (double in C ++) and Integer (int in C ++, but obviously not 64-bit). I used the following code (the code is not on me, so the syntax may be a bit off):

procedure send_data (this : in hidden_ptr; data : in Long_Float; time : in Integer); pragma import (CPP, send_data, "MyClass::sendData"); 

Now that this works, I am trying to extend the time to full 64-bit and ideally would like to have an unsigned long long on the C ++ side. I don't see any types in Ada that match this, so I created my own type:

 type U64 is mod 2 ** 64; 

When using this type with my send_data method, I get a message that there are no possible ways to match this type with the C ++ type (something along these lines, again, I have no code or exact error).

Is there a way to pass a custom type to Ada in C ++? Perhaps there is another type in Ada that I can use as an unsigned 64-bit value that will work? Is there a way to pass an address of my type U64 as a parameter to a C ++ method, if that is easier? I am using the green hills adamulti v3.5 compiler (very new to ada, not sure if this information helps or not). Examples would be greatly appreciated!

+6
source share
1 answer

As an addition to the comment / answer by @KeithThompson ...

The officially supported Ada interface formats are in Interfaces.C , and there is not too long an int or unsigned (in the 2005 version. Is the official 2012 version still?).

You worked correctly on this. If your compiler did not support this, more drastic measures will be required.

The first obvious thing to try is to pass the 64-bit int by reference. This will require changes on the C side.

I know that C / C ++ TIME structures usually have 64-bit values, defined as concatenated structures. So what you can do is define an Ada entry to mimic one of these C structures, make sure it looks like C (for example: with a representation of the representation and dimensions), and then makes this object what uses your imported procedure for its parameter.

After that you will have to pull the nasty tricks of the parameters. For example, you can try changing the Ada import side of this parameter to a 64-bit float, unchecked_converting the actual parameter to a 64-bit float and try to pass it this way. The problem is that many CPUs skip floats in different registers than int. So, most likely, this will not work, and if this happens, it will not be serious.

There may be other ways to fake this if you figure out how your compiler's CPP calling convention works. For example, if it uses two 32-bit registration files to transfer 64-bit ints, you can split the 64-bit int Ada into two and pass it with two parameters on the Ada side. If it passes 64-bit values ​​by reference, you can simply tell the Ada side that you are passing a pointer to your U64. Again, these solutions will not be portable, but they will make you go.

+1
source

Source: https://habr.com/ru/post/925805/


All Articles