XS (от англ. «eXternal Subroutine») — это макроязык интерфейса внешних функций языка программирования Perl, через который программа на языке Perl может вызывать подпрограмму на C или C++.
Макроязык XS описывает интерфейс функций и служит для согласования модели вызова Perl-функций с моделью вызова C-функций, что включает в себя преобразование типов и манипуляции с размещением аргументов функций и возвращаемых значений. Каждую отдельно описанную функцию в интерфейсе принято называть XSUB.
XS используется в тех случаях, когда требуется сделать обёртку или интерфейс к существующим C-библиотекам для использования в Perl.
В программировании на Perl интерфейс между Perl и другими языками также называется расширением. Популярным языком интерфейса, используемым в программировании на Perl, является XS. Язык XS используется в файле описания интерфейса для создания расширенного интерфейса между Perl и кодом на C или C++. Интерфейс XS компонуется с некоторыми библиотеками для создания новой библиотеки, которая может быть либо динамически, либо статически связана с Perl. Описание интерфейса пишется на макроязыке XS и является ключевым компонентом интерфейса расширения Perl.[1]
XSUB формирует основную единицу для интерфейса XS и представляет собой прямой перевод между C/C++ и Perl, поэтому он сохраняет интерфейс. После того, как интерфейс XSUB скомпилирован с использованием компилятора xsubpp, он обеспечивает прямое сопоставление между кодом Perl и C и "склеивает" их вместе.[1]
Библиотеки подпрограмм в Perl называются модулями, а модули, содержащие XSUB, называются модулями XS. Perl предоставляет основу для разработки, упаковки, распространения и установки таких модулей.
Появление XS вызвано необходимостью написания подпрограмм, которые выполняют задачи с очень интенсивным использованием ЦП и/или оперативной памяти, взаимодействуют с оборудованием или низкоуровневыми системными средствами, существующими библиотеками подпрограмм на C.
Можно писать модули XS, которые обертывают код C++. В основном это вопрос настройки системы сборки модулей[2].
![]() | Этот раздел нуждается в переработке. Пожалуйста, уточните проблему в разделе с помощью более узкого шаблона. |
Ниже показан 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.