Spec-Zone.ru › Perl 5.38

perlxstypemap

СОДЕРЖАНИЕ

  • НАЗВАНИЕ
  • ОПИСАНИЕ
    • Структура typemap
    • Роль файла typemap в вашем дистрибутиве
    • Обмен typemap между дистрибутивами CPAN
    • Написание записей typemap
    • Полный список основных typemap

НАЗВАНИЕ

perlxstypemap - Сопоставление типов C/Perl для Perl XS

ОПИСАНИЕ

Чем больше вы задумываетесь об интерфейсе между двумя языками, тем больше вы поймете, что большая часть усилий программиста приходится на преобразование между структурами данных, которые являются родными для каждого из вовлеченных языков. Это важнее других вопросов, таких как различные соглашения о вызовах, потому что пространство проблем гораздо больше. Существует просто больше способов поместить данные в память, чем способов реализовать вызов функции.

Попытка Perl XS решить эту проблему заключается в концепции typemap. На абстрактном уровне typemap Perl XS — это всего лишь рецепт преобразования из определенной структуры данных Perl в определенную структуру данных C и наоборот. Поскольку могут быть типы C, которые достаточно похожи друг на друга, чтобы оправдать преобразование с помощью одной и той же логики, typemap XS представлены уникальным идентификатором, далее в этом документе называемым типом XS. Затем вы можете указать компилятору XS, что несколько типов C должны быть сопоставлены с одним и тем же typemap XS.

В вашем коде XS, когда вы определяете аргумент с типом C или когда вы используете CODE: и OUTPUT: секции вместе с типом возвращаемого значения C вашей XSUB, именно механизм сопоставления типов сделает это простым.

Структура typemap

В более практическом плане typemap — это набор фрагментов кода, используемых компилятором xsubpp для сопоставления параметров и значений функций C со значениями Perl. Файл typemap может состоять из трех разделов, помеченных TYPEMAP, INPUT, и OUTPUT. Немаркированная начальная секция предполагается как TYPEMAP секция. Раздел INPUT сообщает компилятору, как преобразовывать значения Perl в переменные определенных типов C. Раздел OUTPUT сообщает компилятору, как преобразовывать значения из определенных типов C в значения, которые Perl может понять. Раздел TYPEMAP сообщает компилятору, какие фрагменты кода INPUT и OUTPUT должны использоваться для сопоставления данного типа C со значением Perl. Разделы с метками TYPEMAP, INPUT, или OUTPUT должны начинаться в первой колонке на отдельной строке и быть в верхнем регистре.

Каждый тип раздела может появляться произвольное количество раз и вообще может отсутствовать. Например, typemap часто может отсутствовать INPUT и OUTPUT разделы, если ему нужно только связать дополнительные типы C с основными типами XS, такими как T_PTROBJ. Строки, начинающиеся с диеза #, считаются комментариями и игнорируются в TYPEMAP разделе, но считаются значимыми в INPUT и OUTPUT разделах. Пустые строки, как правило, игнорируются.

Традиционно typemap нужно было писать в отдельный файл, обычно называемый typemap в дистрибутиве CPAN. С ExtUtils::ParseXS (компилятор XS) версии 3.12 или лучше, которая поставляется с Perl 5.16, typemap также можно встраивать непосредственно в код XS с помощью синтаксиса типа HERE-doc:

TYPEMAP: <<HERE
...
HERE

где HERE можно заменить другими идентификаторами, как и в обычных Perl HERE-doc. Все детали ниже о текстовом формате typemap остаются действительными.

В TYPEMAP разделе должна быть одна пара типа C и типа XS на строке следующим образом. Пример из файла core typemap:

TYPEMAP
# all variants of char* is handled by the T_PV typemap
char *          T_PV
const char *    T_PV
unsigned char * T_PV
...

Разделы INPUT и OUTPUT имеют одинаковый формат, то есть каждая неотступленная строка начинает новую входную или выходную карту соответственно. Новая входная или выходная карта должна начинаться с имени сопоставляемого типа XS на отдельной строке, за которой следует код, реализующий его, с отступом в следующих строках. Пример:

INPUT
T_PV
  $var = ($type)SvPV_nolen($arg)
T_PTR
  $var = INT2PTR($type,SvIV($arg))

Мы вернёмся к значению этих похожих на Perl переменных чуть позже.

Наконец, вот пример полного файла typemap для сопоставления строк C типа char * со скалярами/строками Perl:

TYPEMAP
char *  T_PV

INPUT
T_PV
  $var = ($type)SvPV_nolen($arg)

OUTPUT
T_PV
  sv_setpv((SV*)$arg, $var);

Вот более сложный пример: предположим, что вы хотели, чтобы struct netconfig был освящён в классе Net::Config. Один из способов сделать это — использовать символы нижнего подчеркивания (_) для разделения имён пакетов следующим образом:

typedef struct netconfig * Net_Config;

А затем предоставить запись typemap T_PTROBJ_SPECIAL, которая сопоставляет символы нижнего подчеркивания с двойными двоеточиями (::), и объявить Net_Config как такого типа:

TYPEMAP
Net_Config      T_PTROBJ_SPECIAL

INPUT
T_PTROBJ_SPECIAL
  if (sv_derived_from($arg, \"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\")){
    IV tmp = SvIV((SV*)SvRV($arg));
    $var = INT2PTR($type, tmp);
  }
  else
    croak(\"$var is not of type ${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\")

OUTPUT
T_PTROBJ_SPECIAL
  sv_setref_pv($arg, \"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\",
               (void*)$var);

Разделы INPUT и OUTPUT динамически подставляют символы нижнего подчеркивания вместо двойных двоеточий, обеспечивая желаемый эффект. Этот пример демонстрирует некоторые возможности и универсальность механизма typemap.

Макрос INT2PTR (определенный в perl.h) преобразует целое число в указатель заданного типа, учитывая возможные различия в размере целых чисел и указателей. Также существуют макросы PTR2IV, PTR2UV, PTR2NV, для преобразования в обратном направлении, что может быть полезно в разделах OUTPUT.

Роль файла typemap в вашем дистрибутиве

По умолчанию typemap в каталоге lib/ExtUtils исходного кода Perl содержит много полезных типов, которые могут использоваться расширениями Perl. Некоторые расширения определяют дополнительные typemap, которые они хранят в собственном каталоге. Эти дополнительные typemap могут ссылаться на разделы INPUT и OUTPUT в основном typemap. Компилятор xsubpp позволит typemap расширения переопределять любые сопоставления, которые находятся в основном typemap. Вместо использования дополнительного файла typemap, typemap могут быть встроены в XS с помощью синтаксиса heredoc. См. документацию по ключевому слову TYPEMAP: XS.

Для дистрибутивов CPAN можно предположить, что типы XS, определенные ядром Perl, уже доступны. Кроме того, основной typemap содержит значения XS по умолчанию для большого числа типов C. Например, если вы просто вернёте char * из своей XSUB, основной typemap свяжет этот тип C с типом T_PV XS. Это означает, что ваша строка C будет скопирована в слот PV (значение указателя) нового скаляра, который будет возвращён из вашей XSUB в Perl.

Если вы разрабатываете дистрибутив CPAN с использованием XS, вы можете добавить свой собственный файл под названием typemap в дистрибутив. Этот файл может содержать typemap, которые либо сопоставляют типы, специфичные для вашего кода, либо переопределяют сопоставления файла основного typemap для общих типов C.

Обмен typemap между дистрибутивами CPAN

Начиная с ExtUtils::ParseXS версии 3.13_01 (поставляется с Perl 5.16 и более поздними версиями), довольно легко обмениваться кодом typemap между несколькими дистрибутивами CPAN. Общая идея заключается в том, чтобы обмениваться им как модулем, который предлагает определённый API, и иметь зависимым модулям объявить это как требование времени компиляции и импортировать typemap в XS. Пример такого модуля typemap-обмена на CPAN — ExtUtils::Typemaps::Basic. Два шага для обеспечения доступности typemap этого модуля в вашем коде:

  • Объявите ExtUtils::Typemaps::Basic как зависимость времени компиляции в Makefile.PL (используйте BUILD_REQUIRES), или в вашем Build.PL (используйте build_requires).

  • Включите следующую строку в раздел XS вашего файла XS: (не разрывайте строку)

    INCLUDE_COMMAND: $^X -MExtUtils::Typemaps::Cmd
                     -e "print embeddable_typemap(q{Basic})"

Написание записей typemap

Каждая запись typemap INPUT или OUTPUT — это строка Perl в двойных кавычках, которая будет вычисляться при наличии определенных переменных, чтобы получить окончательный код C для сопоставления определённого типа C.

Это означает, что вы можете встраивать код Perl в свой код typemap (C) с помощью конструкций, таких как ${ perl code that evaluates to scalar reference here }. Распространённый случай использования — генерация сообщений об ошибках, которые ссылаются на истинное имя функции, даже при использовании функции ALIAS XS:

${ $ALIAS ? \q[GvNAME(CvGV(cv))] : \qq[\"$pname\"] }

Для многих примеров typemap обратитесь к основному файлу typemap, который можно найти в дереве исходного кода Perl в lib/ExtUtils/typemap.

Переменные Perl, которые доступны для интерполяции в typemap, следующие:

  • $var — имя входной или выходной переменной, например RETVAL для значений возврата.

  • $type — исходный тип C параметра, любой : заменённый на _. Например, для типа Foo::Bar, $type равен Foo__Bar

  • $ntype — предоставленный тип с * заменённым на Ptr. Например, для типа Foo*, $ntype равен FooPtr

  • $arg — запись стека, из которой параметр вводится или в которую он выводится, например ST(0)

  • $argoff — смещение аргумента стека аргумента. То есть 0 для первого аргумента и т. д.

  • $pname — полное имя XSUB, включая имя PACKAGE, с любыми PREFIX удалены. Это имя без ALIAS.

  • $Package — пакет, указанный самым последним ключевым словом PACKAGE

  • $ALIAS — ненулевое значение, если текущая XSUB имеет какие-либо псевдонимы, объявленные с ALIAS

Полный список основных typemap

Каждый тип C представлен записью в файле typemap, которая отвечает за преобразование переменных Perl (SV, AV, HV, CV и т. д.) в этот тип и из него. В следующих разделах перечислены все типы XS, которые поставляются с Perl по умолчанию.

T_SV

Это просто передаёт C-представление переменной Perl (SV*) внутрь и наружу слоя XS. Это можно использовать, если C-код хочет работать непосредственно с переменной Perl.

T_SVREF

Используется для передачи ссылки на SV и возврата ссылки на SV.

Обратите внимание, что эта таблица типов не уменьшает счётчик ссылок при возвращении ссылки на SV*. См. также: T_SVREF_REFCOUNT_FIXED

T_SVREF_FIXED

Используется для передачи ссылки на SV и возврата ссылки на SV. Это фиксированная разновидность T_SVREF, которая надлежащим образом уменьшает счётчик ссылок при возвращении ссылки на SV*. Введена в perl 5.15.4.

T_AVREF

На уровне Perl это ссылка на массив Perl. На уровне C это указатель на AV.

Обратите внимание, что эта таблица типов не уменьшает счётчик ссылок при возвращении AV*. См. также: T_AVREF_REFCOUNT_FIXED

T_AVREF_REFCOUNT_FIXED

На уровне Perl это ссылка на массив Perl. На уровне C это указатель на AV. Это фиксированная разновидность T_AVREF, которая надлежащим образом уменьшает счётчик ссылок при возвращении AV*. Введена в perl 5.15.4.

T_HVREF

На уровне Perl это ссылка на хэш Perl. На уровне C это указатель на HV.

Обратите внимание, что эта таблица типов не уменьшает счётчик ссылок при возвращении HV*. См. также: T_HVREF_REFCOUNT_FIXED

T_HVREF_REFCOUNT_FIXED

На уровне Perl это ссылка на хэш Perl. На уровне C это указатель на HV. Это фиксированная разновидность T_HVREF, которая надлежащим образом уменьшает счётчик ссылок при возвращении HV*. Введена в perl 5.15.4.

T_CVREF

На уровне Perl это ссылка на подпрограмму Perl (например, $sub = sub { 1 };). На уровне C это указатель на CV.

Обратите внимание, что эта таблица типов не уменьшает счётчик ссылок при возвращении HV*. См. также: T_HVREF_REFCOUNT_FIXED

T_CVREF_REFCOUNT_FIXED

На уровне Perl это ссылка на подпрограмму Perl (например, $sub = sub { 1 };). На уровне C это указатель на CV.

Это фиксированная разновидность T_HVREF, которая надлежащим образом уменьшает счётчик ссылок при возвращении HV*. Введена в perl 5.15.4.

T_SYSRET

Таблица типов T_SYSRET используется для обработки возвращаемых значений из системных вызовов. Она имеет смысл только при передаче значений из C в Perl (нет понятия передачи значения возврата системного вызова из Perl в C).

Системные вызовы возвращают -1 при ошибке (устанавливая ERRNO с причиной) и (обычно) 0 при успехе. Если возвращаемое значение равно -1, эта таблица типов возвращает undef. Если возвращаемое значение не равно -1, эта таблица типов преобразует 0 (Perl false) в "0 but true" (что является Perl true) или возвращает само значение, чтобы указать, что команда выполнена успешно.

Модуль POSIX широко использует этот тип.

T_UV

Беззнаковое целое число.

T_IV

Знаковое целое число. Оно приводится к необходимому типу целого числа при передаче в C и преобразуется в IV при возвращении в Perl.

T_INT

Знаковое целое число. Эта таблица типов преобразует значение Perl в родной тип целого числа (тип int на текущей платформе). При возвращении значения в Perl оно обрабатывается так же, как и для T_IV.

Её поведение идентично использованию типа int в XS с T_IV.

T_ENUM

Значение перечисления. Используется для передачи компонента перечисления из C. Нет причины передавать значение перечисления в C, так как оно хранится как IV внутри Perl.

T_BOOL

Булевый тип. Это можно использовать для передачи значений true и false в C и из C.

T_U_INT

Это для беззнаковых целых чисел. Оно эквивалентно использованию T_UV, но явно приводит переменную к типу unsigned int. По умолчанию тип для unsigned int — T_UV.

T_SHORT

Короткие целые числа. Это эквивалентно T_IV, но явно приводит возвращаемое значение к типу short. По умолчанию таблица типов для short — T_IV.

T_U_SHORT

Беззнаковые короткие целые числа. Это эквивалентно T_UV, но явно приводит возвращаемое значение к типу unsigned short. По умолчанию таблица типов для unsigned short — T_UV.

T_U_SHORT используется для типа U16 в стандартной таблице типов.

T_LONG

Длинные целые числа. Это эквивалентно T_IV, но явно приводит возвращаемое значение к типу long. По умолчанию таблица типов для long — T_IV.

T_U_LONG

Беззнаковые длинные целые числа. Это эквивалентно T_UV, но явно приводит возвращаемое значение к типу unsigned long. По умолчанию таблица типов для unsigned long — T_UV.

T_U_LONG используется для типа U32 в стандартной таблице типов.

T_CHAR

Одиночные 8-битные символы.

T_U_CHAR

Беззнаковый байт.

T_FLOAT

Число с плавающей точкой. Эта таблица типов гарантирует возврат переменной, приведённой к float.

T_NV

Число с плавающей точкой Perl. Аналогично T_IV и T_UV, тип возвращаемого значения приводится к требуемому числовому типу, а не к конкретному типу.

T_DOUBLE

Число с двойной точностью с плавающей точкой. Эта таблица типов гарантирует возврат переменной, приведённой к double.

T_PV

Строка (char *).

T_PTR

Адрес памяти (указатель). Обычно связан с типом void *.

T_PTRREF

Подобно T_PTR, за исключением того, что указатель хранится в скаляре, и ссылка на этот скаляр возвращается вызывающей стороне. Это можно использовать для скрытия фактического значения указателя от программиста, так как оно обычно не требуется непосредственно из Perl.

Таблица типов проверяет, что ссылка на скаляр передаётся из Perl в XS.

T_PTROBJ

Подобно T_PTRREF, за исключением того, что ссылка благословлена в класс. Это позволяет использовать указатель как объект. Чаще всего используется для работы со C-структурами. Таблица типов проверяет, что переданный в процедуру XS perl-объект принадлежит правильному классу (или является частью подкласса).

Указатель благословляется в класс, производный от имени типа указателя, но со всеми '*' в имени, заменёнными на 'Ptr'.

Только для XSUB-функций DESTROY, T_PTROBJ оптимизируется до T_PTRREF. Это означает, что проверка класса пропускается.

T_REF_IV_REF

ЕЩЁ НЕ ГОТОВО

T_REF_IV_PTR

Подобно T_PTROBJ в том, что указатель благословляется в скалярный объект. Разница в том, что когда объект передаётся обратно в XS, он должен быть правильного типа (наследование не поддерживается), в то время как T_PTROBJ поддерживает наследование.

Указатель благословляется в класс, производный от имени типа указателя, но со всеми '*' в имени, заменёнными на 'Ptr'.

Только для XSUB-функций DESTROY, T_REF_IV_PTR оптимизируется до T_PTRREF. Это означает, что проверка класса пропускается.

T_PTRDESC

ЕЩЁ НЕ ГОТОВО

T_REFREF

Подобно T_PTRREF, за исключением того, что указатель, хранящийся в ссылающемся скаляре, разыменовывается и копируется в выходную переменную. Это означает, что T_REFREF к T_PTRREF так же, как T_OPAQUE к T_OPAQUEPTR. Всё ясно?

Реализована только часть ВВОДА (Perl в XSUB), и нет известных пользователей в ядре или на CPAN.

T_REFOBJ

Как T_REFREF, за исключением того, что выполняется строгая проверка типов (наследование не поддерживается).

Только для XSUB-функций DESTROY, T_REFOBJ оптимизируется до T_REFREF. Это означает, что проверка класса пропускается.

T_OPAQUEPTR

Можно использовать для хранения байтов в строковой части SV. Здесь представление данных не имеет значения для Perl, и сами байты просто хранятся в SV. Предполагается, что C-переменная является указателем (байты копируются из этого местоположения в памяти). Если указатель указывает на что-то, что представлено 8 байтами, эти 8 байтов хранятся в SV (и length() вернёт значение 8). Эта запись аналогична T_OPAQUE.

В принципе, команда unpack() может быть использована для преобразования байтов обратно в число (если известен базовый тип).

Эта запись может использоваться для хранения C-структуры (количество байтов для копирования рассчитывается с помощью C-функции sizeof) и может использоваться как альтернатива T_PTRREF, не беспокоясь о утечке памяти (так как Perl очистит SV).

T_OPAQUE

Это можно использовать для хранения данных из типов, не являющихся указателями, в строковой части SV. Это аналогично T_OPAQUEPTR, за исключением того, что таблица типов получает указатель непосредственно, а не предполагает его. Например, если целое число импортируется в Perl с помощью T_OPAQUE вместо T_IV, базовые байты, представляющие целое число, будут храниться в SV, но фактическое значение целого числа недоступно. Т.е. данные невидимы для Perl.

Данные можно извлечь с помощью функции unpack, если известен базовый тип потока байтов.

T_OPAQUE поддерживает ввод и вывод простых типов. T_OPAQUEPTR может использоваться для передачи этих байтов обратно в C, если указатель приемлем.

Неявный массив

xsubpp поддерживает специальный синтаксис для возврата упакованных C-массивов в Perl. Если тип возвращаемого значения XS задаётся как

array(type, nelem)

xsubpp скопирует содержимое nelem * sizeof(type) байтов из RETVAL в SV и поместит его в стек. Это действительно полезно только если количество элементов для возврата известно на этапе компиляции, и вы не против иметь строку байтов в вашем SV. Используйте T_ARRAY для добавления переменного количества аргументов в стек возврата (они не будут упакованы в одну строку).

Это аналогично использованию T_OPAQUEPTR, но может использоваться для обработки более одного элемента.

T_PACKED

Вызывает пользовательские функции для преобразования. Для OUTPUT (XSUB в Perl) вызывается функция с именем XS_pack_$ntype со скаляром Perl на выходе и C-переменной для преобразования. $ntype — нормализованный C-тип, который необходимо сопоставить с Perl. Нормализованный означает, что все * заменены строкой Ptr. Возвращаемое значение функции игнорируется.

И наоборот, для сопоставления INPUT (Perl в XSUB) вызывается функция с именем XS_unpack_$ntype с входным скаляром Perl в качестве аргумента, и возвращаемое значение приводится к сопоставленному C-типу и присваивается выходной C-переменной.

Пример функции преобразования для структурированного типа foo_t * может быть:

static void
XS_pack_foo_tPtr(SV *out, foo_t *in)
{
  dTHX; /* alas, signature does not include pTHX_ */
  HV* hash = newHV();
  hv_stores(hash, "int_member", newSViv(in->int_member));
  hv_stores(hash, "float_member", newSVnv(in->float_member));
  /* ... */

  /* mortalize as thy stack is not refcounted */
  sv_setsv(out, sv_2mortal(newRV_noinc((SV*)hash)));
}

Преобразование из Perl в C оставлено читателю в качестве упражнения, но прототип будет:

static foo_t *
XS_unpack_foo_tPtr(SV *in);

Вместо фактической C-функции, которая должна извлекать контекст потока, используя dTHX, вы можете определить макросы с тем же именем и избежать накладных расходов. Также помните о возможном освобождении памяти, выделенной XS_unpack_foo_tPtr.

T_PACKEDARRAY

T_PACKEDARRAY похож на T_PACKED. Фактически, INPUT (Perl to XSUB) typemap идентичен, но OUTPUT typemap передает дополнительный аргумент функции XS_pack_$ntype. Этот третий параметр указывает количество элементов в выводе, чтобы функция могла адекватно обрабатывать массивы C. Переменная должна быть объявлена пользователем и должна иметь имя count_$ntype, где $ntype — это нормализованное имя типа C, как описано выше. Подпись функции в приведённом примере и foo_t ** была бы следующей:

static void
XS_pack_foo_tPtrPtr(SV *out, foo_t *in, UV count_foo_tPtrPtr);

Тип третьего параметра произволен с точки зрения typemap. Он просто должен соответствовать объявленной переменной.

Конечно, если вам не известно количество элементов в массиве C sometype ** в вашем XSUB, значение, возвращаемое foo_t ** XS_unpack_foo_tPtrPtr(...), будет трудно интерпретировать. Поскольку все детали зависят от автора XS (пользователя typemap), есть несколько решений, ни одно из которых не является особенно элегантным. Наиболее часто встречаемое решение состоит в выделении памяти для N+1 указателей и присвоении NULL (N+1)-му указателю для облегчения итерации.

В качестве альтернативы, возможно, предпочтительнее использовать настроенный typemap для ваших нужд в первую очередь.

T_DATAUNIT

ЕЩЁ НЕ ГОТОВО

T_CALLBACK

ЕЩЁ НЕ ГОТОВО

T_ARRAY

Используется для преобразования списка аргументов Perl в массив C и для помещения содержимого массива C в стек аргументов Perl.

Обычная подпись вызова:

@out = array_func( @in );

Перед массивом может быть любое количество аргументов, но входной и выходной массивы должны быть последними элементами в списке.

При передаче списка Perl в C автор XS должен предоставить функцию (названную по имени типа массива, но с заменой '*' на 'Ptr'), которая выделяет память для хранения списка. Должен быть возвращён указатель. Автор XS должен освободить память при выходе из функции. Переменная ix_$var устанавливается в количество элементов в новом массиве.

При возвращении массива C в Perl автор XS должен предоставить целочисленную переменную, называемую size_$var, содержащую количество элементов в массиве. Это используется для определения того, сколько элементов должно быть помещено в стек возвращаемых аргументов. Это не требуется на входе, так как Perl знает, сколько аргументов находится в стеке при вызове процедуры. Обычно эта переменная называлась бы size_RETVAL.

Кроме того, тип каждого элемента определяется типом массива. Если массив использует тип intArray *, xsubpp автоматически определит, что он содержит переменные типа int, и воспользуется этим элементом typemap для выполнения копирования каждого элемента. Все метки '*' и 'Array' удаляются из имени для определения подтипа.

T_STDIO

Используется для передачи дескрипторов файлов Perl в C и из C с использованием структур FILE *.

T_INOUT

Используется для передачи дескрипторов файлов Perl в C и из C с использованием структур PerlIO *. Дескриптор файла можно использовать для чтения и записи. Соответствует режиму +<, см. также T_IN и T_OUT.

Для получения дополнительной информации об абстракции ввода-вывода Perl см. perliol. Perl должен быть скомпилирован с -Duseperlio.

Проверки того, что дескриптор файла, переданный из Perl в C, был создан с правильным режимом open(), нет.

Подсказка: учебник perlxstut подробно описывает типы XS T_INOUT, T_IN и T_OUT.

T_IN

Аналогично T_INOUT, но дескриптор файла, возвращаемый из C в Perl, может использоваться только для чтения (режим <).

T_OUT

Аналогично T_INOUT, но дескриптор файла, возвращаемый из C в Perl, настроен для использования режима открытия +>.

© 1993–2023 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.38.0/perlxstypemap

Spec-Zone.ru

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