You note in a comment that you are using void*
"because it should be able to accept an address, not just a string.
So, you need to ask how the generic pointer translates to Ada, especially in such a way as to use the input and subtype functions. I would say that “nothing” in this context can be resolved as a whole; that is, if you want to maintain the "flexibility" of the design, you must sacrifice the benefits that Ada provides with its typical system. In addition, I affirm that presented as is, it is generally impossible to reliably use it for "nothing."
I say this because there is no method for determining even the length of the contained “nothing”. If it is a string, then the length is indicated with the pointing address, counting sequentially, up to the first NUL character (ASCII 0). However, there is no way to determine the length if it is not a string (how to know the length / size of an array [1,2,3] or OBJECT) ... and therefore we have no method for determining even the length of "nothing".
Determining the length is an important factor when writing stable / secure code, because if you do not, you cause a buffer overflow.
But, if this can be done, if you can provide some information about the data, whether through a parameter or by changing my_struct
, then we can use this information to build a better type conversion. (In general, the more information you have about a type, the better, because you can verify the validity of the data in ways you could not before, or, even better, verify that this is a compiler for you.)
Type Data_Type is Array( Positive Range <> ) of Interfaces.Unsigned_8; For Data_Type'Component_Size Use 8; Function Some_Data( Stream : not null access Ada.Streams.Root_Stream_Type'Class; Length : In Positive ) Return Data_Type is begin Return Result : Data_Type(1..Length) do For Index in Result'Range loop Interfaces.Unsigned_8'Read(Stream, Result(Index)); end Loop; End Return; end Some_Data;
You can use the above to create an array of 8-bit unsigned integers that will contain data from the stream. It describes what you need to do in the general case, although since you are working with C-import, you can change it a bit so that: a) there is a Temp
variable, which is an array of type Result
, but use For Temp'Address Use [...]
to overlay it on my_type.value, and then use the for-loop to copy it.