Вы упоминаете в комментарии, что используете void*
«потому что он должен быть в состоянии взять адрес чего угодно;не просто строка. ”
Итак, нужно спросить, как общий указатель переводится в Аду, особенно таким образом, чтобы воспользоваться преимуществами функций ввода и подтипа.Я бы сказал, что «что-нибудь» в этом контексте не может быть решено вообще;то есть, если вы хотите сохранить «гибкость» конструкции, вы должны пожертвовать преимуществами, которые Ada обеспечивает своей системой типов.Кроме того, я утверждаю, что представленный как есть, как правило, невозможно надежно использовать для «чего-либо».
Я говорю это, потому что нет способа определить даже длину содержащегося «чего-либо». Если этострока, длина которой начинается от указанного адреса, считая последовательно, до первого символа NUL (ASCII 0).Однако нет способа определить длину, если она не является строкой (как мы узнаем длину / размер массива [1,2,3] или OBJECT) ... и поэтому у нас нет метода для определения дажедлина «всего».
Определение длины является важным фактором при написании стабильного / безопасного кода, потому что, если вы этого не делаете, вы вызываете переполнение буфера.
НоЕсли не включать, если вы можете предоставить некоторую информацию о данных, будь то с помощью параметра или изменения my_struct
, то мы можем использовать эту информацию для создания лучшего преобразования типов.(В общем, чем больше у вас информации о типе, тем лучше, потому что вы можете проверить достоверность данных так, как раньше не могли; или еще лучше, чтобы компилятор проверил это за вас.)
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;
Вы можете использовать вышеупомянутое, чтобы сгенерировать массив 8-разрядных целых чисел без знака, который будет содержать данные из потока.Он описывает, что вам нужно сделать в общем случае, хотя, поскольку вы работаете с C-import, вы можете немного изменить его, чтобы: а) была переменная Temp
, представляющая собой массив типа Result
но используйте For Temp'Address Use [...]
, чтобы наложить его на my_type.value, а затем используйте цикл for, чтобы скопировать его.