Справочное руководство по Ada 2012
B.3.1 Пакет интерфейсов Interfaces.C.Strings
Пакет Interfaces.C.Strings объявляет типы и подпрограммы, позволяющие Ada-программе выделять, ссылаться, обновлять и освобождать строки в стиле C. В частности, частный тип chars_ptr соответствует общему использованию «char *» в C-программах, и объект этого типа может быть передан подпрограмме, для которой указаны with Import => True, Convention => C, а тип аргумента C-функции — «char *».
Статические семантика
Библиотечный пакет Interfaces.C.Strings имеет следующее объявление:
package Interfaces.C.Strings is
pragma Preelaborate(Strings);
pragma Preelaborate(Strings);
type char_array_access is access all char_array;
type chars_ptr is private;
pragma Preelaborable_Initialization(chars_ptr);
pragma Preelaborable_Initialization(chars_ptr);
type chars_ptr_array is array (size_t range <>) of aliased chars_ptr;
Null_Ptr : constant chars_ptr;
function To_Chars_Ptr (Item : in char_array_access;
Nul_Check : in Boolean := False)
return chars_ptr;
Nul_Check : in Boolean := False)
return chars_ptr;
function New_Char_Array (Chars : in char_array) return chars_ptr;
function New_String (Str : in String) return chars_ptr;
procedure Free (Item : in out chars_ptr);
Dereference_Error : exception;
function Value (Item : in chars_ptr) return char_array;
function Value (Item : in chars_ptr; Length : in size_t)
return char_array;
return char_array;
function Value (Item : in chars_ptr) return String;
function Value (Item : in chars_ptr; Length : in size_t)
return String;
return String;
function Strlen (Item : in chars_ptr) return size_t;
procedure Update (Item : in chars_ptr;
Offset : in size_t;
Chars : in char_array;
Check : in Boolean := True);
Offset : in size_t;
Chars : in char_array;
Check : in Boolean := True);
procedure Update (Item : in chars_ptr;
Offset : in size_t;
Str : in String;
Check : in Boolean := True);
Offset : in size_t;
Str : in String;
Check : in Boolean := True);
Update_Error : exception;
private
... -- не определено языком
end Interfaces.C.Strings;
... -- не определено языком
end Interfaces.C.Strings;
Тип chars_ptr совместим с C и соответствует использованию C's «char *» для указателя на первый символ в массиве char, завершаемом нулём. При объявлении объекта типа chars_ptr его значение по умолчанию устанавливается в Null_Ptr, если объект не импортирован (см. B.1).
function To_Chars_Ptr (Item : in char_array_access;
Nul_Check : in Boolean := False)
return chars_ptr;
Nul_Check : in Boolean := False)
return chars_ptr;
Если Item равен null, то To_Chars_Ptr возвращает Null_Ptr. Если Item не равен null, Nul_Check равен True, и Item.all не содержит nul, то функция распространяет Terminator_Error; в противном случае To_Chars_Ptr выполняет преобразование указателя без выделения памяти.
function New_Char_Array (Chars : in char_array) return chars_ptr;
Эта функция возвращает указатель на выделенный объект, инициализированный Chars(Chars'First .. Index) & nul, где
Index = Chars'Last, если Chars не содержит nul, или
Index — наименьшее значение size_t I такое, что Chars(I+1) = nul.
Storage_Error распространяется, если выделение не удаётся.
function New_String (Str : in String) return chars_ptr;
Эта функция эквивалентна New_Char_Array(To_C(Str)).
procedure Free (Item : in out chars_ptr);
Если Item равен Null_Ptr, то Free не оказывает никакого влияния. В противном случае Free освобождает занимаемую Value(Item) память и сбрасывает Item в Null_Ptr.
function Value (Item : in chars_ptr) return char_array;
Если Item = Null_Ptr, то Value распространяет Dereference_Error. В противном случае Value возвращает префикс массива char, на который указывает Item, до и включая первый nul. Нижняя граница результата — 0. Если Item не указывает на строку, завершающуюся nul, то выполнение Value является ошибочным.
function Value (Item : in chars_ptr; Length : in size_t)
return char_array;
return char_array;
Если Item = Null_Ptr, то Value распространяет Dereference_Error. В противном случае Value возвращает меньший из двух массивов: либо первые Length символов, на которые указывает Item, либо Value(Item). Нижняя граница результата — 0. Если Length равно 0, то Value распространяет Constraint_Error.
function Value (Item : in chars_ptr) return String;
Эквивалентно To_Ada(Value(Item), Trim_Nul=>True).
function Value (Item : in chars_ptr; Length : in size_t)
return String;
return String;
Эквивалентно To_Ada(Value(Item, Length) & nul, Trim_Nul=>True).
function Strlen (Item : in chars_ptr) return size_t;
Возвращает Val'Length–1, где Val = Value(Item); распространяет Dereference_Error, если Item = Null_Ptr.
procedure Update (Item : in chars_ptr;
Offset : in size_t;
Chars : in char_array;
Check : Boolean := True);
Offset : in size_t;
Chars : in char_array;
Check : Boolean := True);
Если Item = Null_Ptr, то Update распространяет Dereference_Error. В противном случае эта процедура обновляет значение, на которое указывает Item, начиная с позиции Offset, используя Chars в качестве данных для копирования в массив. Запись нуль-терминатора и пропуск позиции Offset за пределами нуль-терминатора предотвращаются, если Check равен True, как показано ниже:
Пусть N = Strlen(Item). Если Check равен True, то:
Если Offset+Chars'Length>N, то распространяется Update_Error.
В противном случае данные в массиве, на который указывает Item, начиная с символа в позиции Offset, перезаписываются данными из Chars.
Если Check равен False, то обработка выполняется как указано выше, но без проверки, что Offset+Chars'Length>N.
procedure Update (Item : in chars_ptr;
Offset : in size_t;
Str : in String;
Check : in Boolean := True);
Offset : in size_t;
Str : in String;
Check : in Boolean := True);
Эквивалентно Update(Item, Offset, To_C(Str, Append_Nul => False), Check).
Ошибки выполнения
Выполнение любого из следующих действий является ошибочным, если параметр Item не равен null_ptr и Item не указывает на массив char, завершённый нулём.
- Функция Value без параметра Length,
- Процедура Free,
- Функция Strlen.
Выполнение Free(X) также является ошибочным, если chars_ptr X не возвращён New_Char_Array или New_String.
Чтение или обновление освобождённого char_array является ошибкой.
Выполнение Update является ошибочным, если Check равен False и вызов с Check, равным True, вызвал бы Update_Error.
ПРИМЕЧАНИЯ
9 New_Char_Array и New_String могут быть реализованы либо через функцию выделения из C-среды («malloc»), либо через динамическое выделение памяти в Ada («new»). Ключевые моменты
возвращаемое значение (chars_ptr) представляется как C «char *», чтобы его можно было передать в C-функции;
выделенный объект должен быть освобождён программистом путём вызова Free, а не вызываемой C-функцией.