Spec-Zone.ru › Ada 95
Справочник Ada 95

B.3 Взаимодействие с C

Средства, относящиеся к взаимодействию с языком C, — это пакет Interfaces.C и его дочерние пакеты; поддержка директив Import, Export и Convention с convention_идентификатором C; и поддержка директивы Convention с convention_идентификатором C_Pass_By_Copy.
Пакет Interfaces.C содержит основные типы, константы и подпрограммы, которые позволяют программе Ada передавать скаляры и строки функциям C.

Статическая семантика

Библиотечный пакет Interfaces.C имеет следующее объявление:
-- Объявления, основанные на <limits.h> C
CHAR_BIT : constant := определяется реализацией; -- обычно 8
SCHAR_MIN : constant := определяется реализацией; -- обычно -128
SCHAR_MAX : constant := определяется реализацией; -- обычно 127
UCHAR_MAX : constant := определяется реализацией; -- обычно 255
-- Целые со знаком и без знака
type int is range определяется реализацией;
type short is range определяется реализацией;
type long is range определяется реализацией;
type signed_char is range SCHAR_MIN .. SCHAR_MAX;
for signed_char'Size use CHAR_BIT;
type unsigned is mod определяется реализацией;
type unsigned_short is mod определяется реализацией;
type unsigned_long is mod определяется реализацией;
type unsigned_char is mod (UCHAR_MAX+1);
for unsigned_char'Size use CHAR_BIT;
subtype plain_char is определяется реализацией;
type ptrdiff_t is range определяется реализацией;
type size_t is mod определяется реализацией;
-- Числа с плавающей точкой
type C_float is digits определяется реализацией;
type double is digits определяется реализацией;
type long_double is digits определяется реализацией;
-- Символы и строки
type char is <тип символа, определяемый реализацией>;
nul : constant char := определяется реализацией;
function To_C (Item : in Character) return char;
function To_Ada (Item : in char) return Character;
type char_array is array (size_t range <>) of aliased char;
pragma Pack(char_array);
for char_array'Component_Size use CHAR_BIT;
function Is_Nul_Terminated (Item : in char_array) return Boolean;
function To_C (Item : in String;
Append_Nul : in Boolean := True)
return char_array;
function To_Ada (Item : in char_array;
Trim_Nul : in Boolean := True)
return String;
procedure To_C (Item : in String;
Target : out char_array;
Count : out size_t;
Append_Nul : in Boolean := True);
procedure To_Ada (Item : in char_array;
Target : out String;
Count : out Natural;
Trim_Nul : in Boolean := True);
-- Широкий символ и широкая строка
type wchar_t is <тип символа, определяемый реализацией>;
wide_nul : constant wchar_t := определяется реализацией;
function To_C (Item : in Wide_Character) return wchar_t;
function To_Ada (Item : in wchar_t ) return Wide_Character;
type wchar_array is array (size_t range <>) of aliased wchar_t;
pragma Pack(wchar_array);
function Is_Nul_Terminated (Item : in wchar_array) return Boolean;
function To_C (Item : in Wide_String;
Append_Nul : in Boolean := True)
return wchar_array;
function To_Ada (Item : in wchar_array;
Trim_Nul : in Boolean := True)
return Wide_String;
procedure To_C (Item : in Wide_String;
Target : out wchar_array;
Count : out size_t;
Append_Nul : in Boolean := True);
procedure To_Ada (Item : in wchar_array;
Target : out Wide_String;
Count : out Natural;
Trim_Nul : in Boolean := True);
Terminator_Error : exception;
end Interfaces.C;
Каждый из типов, объявленных в Interfaces.C, совместим с C.
Типы int, short, long, unsigned, ptrdiff_t, size_t, double, char и wchar_t соответствуют соответственно типам C с такими же именами. Типы signed_char, unsigned_short, unsigned_long, unsigned_char, C_float и long_double соответствуют соответственно типам C signed char, unsigned short, unsigned long, unsigned char, float и long double.
Тип подтипа plain_char — это либо signed_char, либо unsigned_char, в зависимости от реализации C.
function To_C (Item : in Character) return char;
function To_Ada (Item : in char ) return Character;
Функции To_C и To_Ada преобразуют между типом Ada Character и типом C char.
function Is_Nul_Terminated (Item : in char_array) return Boolean;
Результат Is_Nul_Terminated — True, если Item содержит nul, и False в противном случае.
function To_C (Item : in String; Append_Nul : in Boolean := True)
return char_array;

function To_Ada (Item : in char_array; Trim_Nul : in Boolean := True)
return String;
Результат To_C — значение char_array длины Item'Length (если Append_Nul — False) или Item'Length+1 (если Append_Nul — True). Нижний индекс — 0. Для каждого компонента Item(I), соответствующий компонент результата — To_C, применённый к Item(I). Если Append_Nul — True, то добавляется значение nul.
Результат To_Ada — строка, длина которой равна Item'Length (если Trim_Nul — False) или длине части Item перед первым nul (если Trim_Nul — True). Нижний индекс результата — 1. Если Trim_Nul — False, то для каждого компонента Item(I) соответствующий компонент в результате — To_Ada, применённый к Item(I). Если Trim_Nul — True, то для каждого компонента Item(I) перед первым nul соответствующий компонент в результате — To_Ada, применённый к Item(I). Функция генерирует исключение Terminator_Error, если Trim_Nul — True и Item не содержит nul.
procedure To_C (Item : in String;
Target : out char_array;
Count : out size_t;
Append_Nul : in Boolean := True);

procedure To_Ada (Item : in char_array;
Target : out String;
Count : out Natural;
Trim_Nul : in Boolean := True);
Для процедуры To_C каждый элемент Item преобразуется (через функцию To_C) в char, который присваивается соответствующему элементу Target. Если Append_Nul — True, то nul присваивается следующему элементу Target. В любом случае Count устанавливается в количество назначенных элементов Target. Если Target недостаточно велик, генерируется Constraint_Error.
Для процедуры To_Ada каждый элемент Item (если Trim_Nul — False) или каждый элемент Item перед первым nul (если Trim_Nul — True) преобразуется (через функцию To_Ada) в Character, который присваивается соответствующему элементу Target. Count устанавливается в количество назначенных элементов Target. Если Target недостаточно велик, генерируется Constraint_Error. Если Trim_Nul — True и Item не содержит nul, то генерируется исключение Terminator_Error.
function Is_Nul_Terminated (Item : in wchar_array) return Boolean;
Результат Is_Nul_Terminated — True, если Item содержит wide_nul, и False в противном случае.
function To_C (Item : in Wide_Character) return wchar_t;
function To_Ada (Item : in wchar_t ) return Wide_Character;
To_C и To_Ada обеспечивают соответствие между типами символов Ada и C.
function To_C (Item : in Wide_String;
Append_Nul : in Boolean := True)
return wchar_array;

function To_Ada (Item : in wchar_array;
Trim_Nul : in Boolean := True)
return Wide_String;

procedure To_C (Item : in Wide_String;
Target : out wchar_array;
Count : out size_t;
Append_Nul : in Boolean := True);

procedure To_Ada (Item : in wchar_array;
Target : out Wide_String;
Count : out Natural;
Trim_Nul : in Boolean := True);
Подпрограммы To_C и To_Ada, преобразующие Wide_String и wchar_array, имеют аналогичное действие подпрограммам To_C и To_Ada, преобразующим String и char_array, за исключением того, что используется wide_nul вместо nul.
Директива Convention с convention_идентификатором C_Pass_By_Copy должна применяться только к типу.
Правила применимости в B.1 не применяются к соглашению C_Pass_By_Copy. Вместо этого тип T допускается для соглашения C_Pass_By_Copy, если T является типом записи, не имеющим дискриминантов и имеющим только компоненты со статически ограниченными подтипами, и каждый компонент является C-совместимым.
Если тип совместим с C_Pass_By_Copy, то он также совместим с C.

Требования к реализации

Реализация должна поддерживать pragma Convention с C convention_identifier для C-совместимого типа (см. B.1). Реализация должна поддерживать pragma Convention с C_Pass_By_Copy convention_identifier для типа, совместимого с C_Pass_By_Copy.

Разрешения для реализации

Реализация может предоставить дополнительные объявления в пакетах интерфейса C.

Рекомендации по реализации

Константы nul и wide_nul должны иметь представление нуля.
Реализация должна поддерживать следующие соответствия между Ada и C в интерфейсах.
  • Процедура Ada соответствует функции C, возвращающей void.
  • Функция Ada соответствует функции C, возвращающей не void.
  • Скалярный параметр Ada in передается как скалярный аргумент функции C.
  • Параметр Ada in типа доступа к объекту с указанным типом T передается как t* аргумент функции C, где t — тип C, соответствующий типу Ada T.
  • Параметр Ada access T или параметр Ada out или in out элементарного типа T передается как t* аргумент функции C, где t — тип C, соответствующий типу Ada T. В случае элементарного параметра out или in out используется указатель на временную копию для сохранения семантики передачи по значению.
  • Параметр Ada типа, совместимого с C_Pass_By_Copy (запись) T, режима in, передается как t аргумент функции C, где t — структура C, соответствующая типу Ada T.
  • Параметр Ada типа записи T, любого режима, кроме параметра in совместимого с C_Pass_By_Copy типа, передается как t* аргумент функции C, где t — структура C, соответствующая типу Ada T.
  • Параметр Ada типа массива с типом компонента T, любого режима, передается как t* аргумент функции C, где t — тип C, соответствующий типу Ada T.
  • Параметр Ada типа доступа к подпрограмме передается как указатель на функцию C, шаблон которой соответствует спецификации указанной подпрограммы.
ПРИМЕЧАНИЯ
9 Значения типа char_array не неявно завершаются nul. Если массив char_array должен быть передан в качестве параметра импортированной функции C, требующей завершения nul, то программист несет ответственность за получение этого эффекта.
10 Чтобы получить эффект C's sizeof(item_type), где Item_Type — соответствующий тип Ada, вычислите выражение: size_t(Item_Type'Size/CHAR_BIT).
11 Нет явной поддержки типов объединения C. Для получения эффекта объединений C могут использоваться неконтролируемые преобразования.
12 Функция C, принимающая переменное количество аргументов, может соответствовать нескольким подпрограммам Ada, принимающим разное количество и типы параметров.

Примеры

Пример использования пакета Interfaces.C:
--Вызов функции C Library strcpy
with Interfaces.C;
procedure Test is
package C renames Interfaces.C;
use type C.char_array;
-- Вызов <string.h>strcpy:
-- Определение strcpy в C: char *strcpy(char *s1, const char *s2);
-- Эта функция копирует строку, на которую указывает s2 (включая завершающий нулевой символ),
-- в массив, на который указывает s1. Если копирование происходит между перекрывающимися объектами,
-- поведение не определено. Функция strcpy возвращает значение s1.
-- Примечание: так как возвращаемое значение функции C не нужно, интерфейс Ada — процедура
procedure Strcpy (Target : out C.char_array;
Source : in C.char_array);
pragma Import(C, Strcpy, "strcpy");
Chars1 : C.char_array(1..20);
Chars2 : C.char_array(1..20);
begin
Chars2(1..6) := "qwert" & C.nul;
Strcpy(Chars1, Chars2);
-- Теперь Chars1(1..6) = "qwert" & C.Nul
end Test;


Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API