XS (Perl)
XS — это интерфейс (макроязык) внешней функции Perl, через который программа на языке Perl может вызывать подпрограмму на C или C++. XS (или XSUB) — это аббревиатура от «eXternal Subroutine» (внешняя подпрограмма), где «eXternal» (внешняя) относится к языкам программирования, внешним по отношению к Perl.
Макроязык XS описывает интерфейс функций и служит для согласования модели вызова Perl-функций с моделью вызова C-функций, что включает в себя преобразование типов и манипуляции с размещением аргументов функций и возвращаемых значений. Каждую отдельно описанную функцию в интерфейсе принято называть XSUB.
XS используется в тех случаях, когда требуется сделать обвязки (bindings) или интерфейс к существующим C-библиотекам для использования в Perl.
Основная задача макроязыка XS — упростить написание специфичных модулей, заменяя типовой код обвязки короткими макросами. Однако, XS не отменяет необходимость изучения внутреннего строения Perl и его API. Без их знания написание модулей XS для Perl невозможно.
История появления
Библиотеки подпрограмм в Perl называются модулями, а модули, содержащие XSUB, называются модулями XS. Perl предоставляет основу для разработки, упаковки, распространения и установки таких модулей.
Появление XS вызвано необходимостью написания подпрограмм, которые выполняют задачи с очень интенсивным использованием ЦП и/или оперативной памяти, взаимодействуют с оборудованием или низкоуровневыми системными средствами, существующими библиотеками подпрограмм на C.
Интерпретатор Perl
Интерпретатор Perl — это программа на языке C, поэтому нет принципиальных препятствий для вызова из Perl программ написанных на C. Однако макроязык XS имеет некоторую сложность и достаточно высокотехнологичен, а его использование требует некоторого понимания интерпретатора Perl. Самой ранней ссылкой на эту тему была perlguts POD.
Обёртки
Можно писать модули XS, которые обертывают код C++. В основном это вопрос настройки системы сборки модулей[1].
Пример создания XS-модуля
Ниже показан XS-модуль, который предоставляет функцию concat()
для объединения двух строк (то есть эквивалентная оператору Perl .
).
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
SV* _do_sv_catsv (pTHX_ SV* one_sv, SV* two_sv ) {
SV* one_copy = newSVsv(one_sv);
sv_catsv(one_copy, two_sv);
return one_copy;
}
MODULE = Demo::XSModule PACKAGE = Demo::XSModule
SV*
concat (SV* one_sv, SV* two_sv)
CODE:
SV* to_return = _do_sv_catsv( aTHX_ one_sv, two_sv );
RETVAL = to_return;
OUTPUT:
RETVAL
Первые четыре строки (операторы #define
и #include
) являются стандартным шаблоном.
После этого следует любое количество простых функций C, которые вызываются локально.
Секция, которая начинается с MODULE = Demo::XSModule
, определяет интерфейс Perl для этого кода, используя фактический язык макросов XS. Обратите внимание, что код C в секции CODE:
вызывает функцию чистого C _do_sv_catsv()
, которая была определена в предыдущей секции.
Документация Perl объясняет значение и назначение всех «специальных» символов (например, aTHX_
и RETVAL
), показанных выше.
Чтобы сделать этот модуль доступным для Perl, его необходимо скомпилировать. Инструменты сборки, такие как ExtUtils::MakeMaker, могут делать это автоматически. (Для сборки вручную: инструмент xsubpp анализирует модуль XS и выводит исходный код C; этот исходный код затем компилируется в общую библиотеку и помещается в каталог, где Perl может его найти.) Код Perl затем использует для загрузки и компиляции XS-модуля XSLoader. На этом этапе Perl может вызвать Demo::XSModule::concat('foo', 'bar')
и получить обратно результат в виде строки foobar
, как если бы concat()
сам был написан на Perl.
Обратите внимание, что для создания интерфейсов Perl к уже существующим С-библиотекам, инструмент h2xs может автоматизировать большую часть создания самого файла XS.
Сложности
Создание и обслуживание модулей XS требует опыта работы с самим C, а также с обширным C API Perl. Модули XS могут быть установлены только в том случае, если доступны компилятор C и файлы заголовков, с которыми был скомпилирован интерпретатор Perl. Кроме того, новые версии Perl могут нарушить бинарную совместимость, требуя перекомпиляции модулей XS.
См. также
Литература
- Jenness, Tim & Cozens, Simon (2002). «Extending and Embedding Perl». Greenwich: Manning Publications Co. ISBN 1-930110-82-0
- Gluing C++ And Perl Together . johnkeiser.com (August 27, 2001).
Ссылки
- perlxs (англ.) Perl XS application programming interface
- perlxstut (англ.) Perl XS tutorial
- perlguts (англ.) Perl internal functions for those doing extensions
- perlapi (англ.) Perl API listing (autogenerated)
- XS Mechanics (англ.) tutorial
- Perl and C++ (англ.) building XS modules for C++
- xs-fun (англ.) XS is fun: a simple and easy tutorial on writing Perl XS
- Mеханика XS
- Введение в Perl XS
- HOWTO по работе с С++ классами из Perl'a
- Использование С++ классов в Perl скриптах