<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://wiki2.linuxformat.ru/skins/common/feed.css?97"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://wiki2.linuxformat.ru/index.php?action=history&amp;feed=atom&amp;title=LXF98%3APerl_%D0%B8_C%2B%2B</id>
		<title>LXF98:Perl и C++ - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://wiki2.linuxformat.ru/index.php?action=history&amp;feed=atom&amp;title=LXF98%3APerl_%D0%B8_C%2B%2B"/>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF98:Perl_%D0%B8_C%2B%2B&amp;action=history"/>
		<updated>2026-05-13T22:28:24Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.11.1</generator>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF98:Perl_%D0%B8_C%2B%2B&amp;diff=6503&amp;oldid=prev</id>
		<title>Yaleks: /* Взаимодействие с STL или ее аналогами */</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF98:Perl_%D0%B8_C%2B%2B&amp;diff=6503&amp;oldid=prev"/>
				<updated>2009-01-07T12:30:50Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Взаимодействие с STL или ее аналогами&lt;/span&gt;&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Предыдущая&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Версия 12:30, 7 января 2009&lt;/td&gt;
			&lt;/tr&gt;
		&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 417:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 417:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt; &lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt; QByteArray *                O_OBJECT&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt; QByteArray *                O_OBJECT&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/&lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;sorce&lt;/del&gt;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/&lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;source&lt;/ins&gt;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;и создании для этого класса модуля '''lib/QtCore/QByteArray.pm'''. Функция &amp;lt;font color=darkred&amp;gt;_split&amp;lt;/font&amp;gt; возвращает указатель на массив, однако в программе удобнее пользоваться обычным массивом. С этой целью напишем простейшую оболочку для этой функции. Кроме того, в Perl'e есть своя функция &amp;lt;font color=darkred&amp;gt;split&amp;lt;/font&amp;gt;, поэтому ее надо переопределить в пакете, используя &amp;lt;font color=darkred&amp;gt;use subs&amp;lt;/font&amp;gt;.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;и создании для этого класса модуля '''lib/QtCore/QByteArray.pm'''. Функция &amp;lt;font color=darkred&amp;gt;_split&amp;lt;/font&amp;gt; возвращает указатель на массив, однако в программе удобнее пользоваться обычным массивом. С этой целью напишем простейшую оболочку для этой функции. Кроме того, в Perl'e есть своя функция &amp;lt;font color=darkred&amp;gt;split&amp;lt;/font&amp;gt;, поэтому ее надо переопределить в пакете, используя &amp;lt;font color=darkred&amp;gt;use subs&amp;lt;/font&amp;gt;.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt; &lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Yaleks</name></author>	</entry>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF98:Perl_%D0%B8_C%2B%2B&amp;diff=4535&amp;oldid=prev</id>
		<title>Lockal: восстановление кавычек в коде  AWB</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF98:Perl_%D0%B8_C%2B%2B&amp;diff=4535&amp;oldid=prev"/>
				<updated>2008-04-27T14:52:05Z</updated>
		
		<summary type="html">&lt;p&gt;восстановление кавычек в коде  &lt;a href=&quot;/index.php?title=Linuxformat:AutoWikiBrowser&amp;amp;action=edit&quot; class=&quot;new&quot; title=&quot;Linuxformat:AutoWikiBrowser&quot;&gt;AWB&lt;/a&gt;&lt;/p&gt;
&lt;a href=&quot;http://wiki2.linuxformat.ru/index.php?title=LXF98:Perl_%D0%B8_C%2B%2B&amp;amp;diff=4535&amp;amp;oldid=3581&quot;&gt;(Различия между версиями)&lt;/a&gt;</summary>
		<author><name>Lockal</name></author>	</entry>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF98:Perl_%D0%B8_C%2B%2B&amp;diff=3581&amp;oldid=prev</id>
		<title>Belogorie: Новая: ==&lt;font color=darkred&gt;Как работать&lt;/font&gt; с классами С++ из Perl==  ''Огорчены, что PerlQt застрял на версии 3.008?Не беспокой...</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF98:Perl_%D0%B8_C%2B%2B&amp;diff=3581&amp;oldid=prev"/>
				<updated>2008-03-27T13:35:19Z</updated>
		
		<summary type="html">&lt;p&gt;Новая: ==&amp;lt;font color=darkred&amp;gt;Как работать&amp;lt;/font&amp;gt; с классами С++ из Perl==  ''Огорчены, что PerlQt застрял на версии 3.008?Не беспокой...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая статья&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==&amp;lt;font color=darkred&amp;gt;Как работать&amp;lt;/font&amp;gt; с классами С++ из Perl==&lt;br /&gt;
&lt;br /&gt;
''Огорчены, что PerlQt застрял на версии 3.008?Не беспокойтесь – '''Вадим Лихота''' расскажет, как решить подобную задачу своими силами. Если, конечно, хватит терпения.''&lt;br /&gt;
&lt;br /&gt;
Описаний того, как импортировать в Perl функции из С, достаточно много, а вот информацию об использовании классов C++ я встречал в виде кратких описаний только в “''XS Cookbook''” &amp;lt;font color=darkblue&amp;gt;[1, 2]&amp;lt;/font&amp;gt; и небольшой статье &amp;lt;font color=darkblue&amp;gt;[4]&amp;lt;/font&amp;gt;. Пример использования класса С++ в Perl’е из “''XS Cookbook''” в сокращенном варианте перекочевал в perlxstut. Кроме того, на CPAN можно найти модули, импортирующие классы С++ и имеющие файлы импорта, которые можно использовать в качестве примера, такие, как Boost-Graph, Lucene, Search-Xapian,Однако они не покрывают многих вариантов подключения классов.&lt;br /&gt;
&lt;br /&gt;
Чтобы не умножать сущности без надобности, т.е. не писать новых классов, которые потом нигде не пригодятся, воспользуемся уже готовой библиотекой ''QtCore'' из состава ''Qt4''. Для удобства я буду приводить части заголовочных файлов этой библиотеки, но все примеры будут работоспособны при подключении реальной библиотеки. Кроме того, использование файла '''perlobject.map''' &amp;lt;font color=darkblue&amp;gt;[3]&amp;lt;/font&amp;gt; позволит не писать заново описание объектов.&lt;br /&gt;
&lt;br /&gt;
===Начальные данные для любого модуля===&lt;br /&gt;
&lt;br /&gt;
Начальные данные для любого модуля можно найти в уже упомянутой статье &amp;lt;font color=darkblue&amp;gt;[4]&amp;lt;/font&amp;gt;, однако они столь ценны и необходимы для раскрытия темы, что заслуживают отдельного рассмотрения. Скелет любого модуля можно написать вручную, но легче и быстрее это делается командой &amp;lt;font color=darkred&amp;gt;h2xs -An имя_модуля&amp;lt;/font&amp;gt;. В результате будет создан каталог для модуля с необходимыми файлами, содержимое которых детально описано в «Программировании на Perl» &amp;lt;font color=darkblue&amp;gt;[5]&amp;lt;/font&amp;gt;. Дав команду &amp;lt;font color=darkred&amp;gt;h2xs -An QtCore&amp;lt;/font&amp;gt;, вы&lt;br /&gt;
получите скелет модуля. В созданный каталог QtCore необходимо скопировать '''perobject.map''' (названия всех файлов приводятся относительно каталога '''QtCore'''). Созданный файл '''Makefile.PL''' надо привести к следующему виду:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 use 5.008;&lt;br /&gt;
 use ExtUtils::MakeMaker;&lt;br /&gt;
 $CC = ‘g++’;&lt;br /&gt;
 WriteMakefile(&lt;br /&gt;
      NAME                 =&amp;gt; ‘QtCore’,&lt;br /&gt;
      VERSION_FROM         =&amp;gt; ‘lib/QtCore.pm’,&lt;br /&gt;
      PREREQ_PM              =&amp;gt; {}, # e.g., Module::Name =&amp;gt; 1.1&lt;br /&gt;
      ($] &amp;gt;= 5.005 ?&lt;br /&gt;
           (ABSTRACT_FROM           =&amp;gt; ‘lib/QtCore.pm’,&lt;br /&gt;
           AUTHOR              =&amp;gt; ‘A. U. Thor &amp;lt;author@localdomain&amp;gt;’) : ()),&lt;br /&gt;
      LIBS                =&amp;gt; [‘’],&lt;br /&gt;
      DEFINE          =&amp;gt; ‘’,&lt;br /&gt;
      CC               =&amp;gt; $CC,&lt;br /&gt;
      LD               =&amp;gt; ‘$(CC)’,&lt;br /&gt;
      INC               =&amp;gt; ‘’,&lt;br /&gt;
      # OBJECT            =&amp;gt; ‘$(O_FILES)’,&lt;br /&gt;
      XSOPT                 =&amp;gt; ‘-C++’,&lt;br /&gt;
      TYPEMAPS             =&amp;gt; [‘perlobject.map’],&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Выделенные жирным строки необходимо добавить именно для того, чтобы Perl заработал с С++.&lt;br /&gt;
&lt;br /&gt;
Кроме того, важно исправить файл '''QtCore.xs''', который будет содержать импортируемые в Perl функции:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 #ifdef __cplusplus&lt;br /&gt;
 extern “C” {&lt;br /&gt;
 #endif&lt;br /&gt;
 #include “EXTERN.h”&lt;br /&gt;
 #include “perl.h”&lt;br /&gt;
 #include “XSUB.h”&lt;br /&gt;
 #ifdef __cplusplus&lt;br /&gt;
 }&lt;br /&gt;
 #endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Для наглядного примера создадим в этом файле класс, который будет хранить, допустим, версию программы. Для этого добавим класс после подключенных заголовочных файлов перед строкой &amp;lt;font color=darkred&amp;gt;MODULE = QtCore PACKAGE = QtCore&amp;lt;/font&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 class QtCore {&lt;br /&gt;
 public:&lt;br /&gt;
      QtCore(){ vers = 0.001; };&lt;br /&gt;
      ~QtCore(){};&lt;br /&gt;
      double ver(){ return vers; };&lt;br /&gt;
      void setVer(double v){ vers = v; };&lt;br /&gt;
 private:&lt;br /&gt;
      double vers;&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Работа с обычными функциями, конструктором и деструктором уже предусмотрена в Perl XS, поэтому после объявления модуля и пакета можно использовать краткие объявления функций (также возможны комментарии в perl-стиле):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 MODULE = QtCore           PACKAGE = QtCore&lt;br /&gt;
 =comment&lt;br /&gt;
 явное указание использовать прототипы функций позволяет &lt;br /&gt;
 избежать некоторых ошибок при передаче параметров в функции, но&lt;br /&gt;
 в тоже время не дает упростить использование этих функций.&lt;br /&gt;
 Например, если функция получает два параметра, а ваши данные для&lt;br /&gt;
 нее хранятся в массиве @aa, то ее необходимо вызывать как&lt;br /&gt;
 my_func($aa[0], $aa[1]).&lt;br /&gt;
 Тогда как при указании “PROTOTYPES: DISABLE” можно эту функцию&lt;br /&gt;
 вызвать как my_func(@aa).&lt;br /&gt;
 =cut&lt;br /&gt;
 PROTOTYPES: ENABLE&lt;br /&gt;
 =comment&lt;br /&gt;
 XS распознает только один конструктор -- “new”. Если их будет&lt;br /&gt;
 больше, то каждый нуждается в подробном описании.&lt;br /&gt;
 =cut&lt;br /&gt;
 QtCore *&lt;br /&gt;
 QtCore::new()&lt;br /&gt;
 =comment&lt;br /&gt;
 методы класса&lt;br /&gt;
 =cut&lt;br /&gt;
 double&lt;br /&gt;
 QtCore::ver()&lt;br /&gt;
 void&lt;br /&gt;
 QtCore::setVer(v)&lt;br /&gt;
      double v&lt;br /&gt;
 =comment&lt;br /&gt;
 В подавляющем большинстве случаев такого вызова деструктора&lt;br /&gt;
 хватает.&lt;br /&gt;
 Однако если вы хотите явно освободить память, уничтожить&lt;br /&gt;
 зависимые объекты и т.п., то пример вызова деструктора найдете в&lt;br /&gt;
 XS Cookbook [2, ArrayOfStruct].&lt;br /&gt;
 =cut&lt;br /&gt;
 void&lt;br /&gt;
 QtCore::DESTROY() &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Кроме того, для вызова класса следует указать Perl’у, чем является класс &amp;lt;font color=darkred&amp;gt;QtCore&amp;lt;/font&amp;gt;, т.е. как работать с этим типом данных, для чего создадим файл '''typemap''' со следующим содержимым:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 TYPEMAP&lt;br /&gt;
 QtCore * O_OBJECT&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Описания встроенных типов данных представлены в '''typemap.xs''' &amp;lt;font color=darkblue&amp;gt;[6]&amp;lt;/font&amp;gt;, а описание &amp;lt;font color=darkred&amp;gt;O_OBJECT&amp;lt;/font&amp;gt; находится в файле '''perlobject.map'''. Если не добавлять этот файл, то придется самостоятельно полностью описывать все дополнительные типы данных в файле '''typemap''' (пример подобного описания приводится ниже). После этого остается внести изменения в файл '''lib/QtCore.pm''', который и будет подключаться в конечных скриптах. Поскольку '''QtCore.pm''' будет объектом, и ничего экспортироваться из него не будет, то следует убрать из этого файла все относящееся к модулю &amp;lt;font color=darkred&amp;gt;Exporter&amp;lt;/font&amp;gt;. Для импорта внешних функций можно использовать как &amp;lt;font color=darkred&amp;gt;XSLoader&amp;lt;/font&amp;gt;, так и более старый &amp;lt;font color=darkred&amp;gt;DynaLoader&amp;lt;/font&amp;gt; (я использовал второй, т.к. к нему чаще обращаются).&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 package QtCore;&lt;br /&gt;
 use 5.008;&lt;br /&gt;
 use strict;&lt;br /&gt;
 use warnings;&lt;br /&gt;
 require DynaLoader;&lt;br /&gt;
 our @ISA = qw(DynaLoader);&lt;br /&gt;
 our $VERSION = ‘0.01’;&lt;br /&gt;
 bootstrap QtCore $VERSION;&lt;br /&gt;
 1;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Чтобы собрать полученный модуль, выполните команды '''perl Makefile.PL &amp;amp;&amp;amp; make'''.&lt;br /&gt;
&lt;br /&gt;
Все сделанное необходимо протестировать. В модуле уже есть каталог '''t/''' для тестовых скриптов, которые, однако, расчитаны только на то, чтоб по команде '''make test''' вывести “'''имя_скрипта.....ok'''”. Этого явно недостаточно, чтобы подробно просмотреть работоспособность написанного модуля. Поэтому создадим каталог '''test/''' со скриптом '''qtcore.pl''' и следующим содержимым:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 #!/usr/bin/perl -w&lt;br /&gt;
 use blib;&lt;br /&gt;
 use QtCore;&lt;br /&gt;
 my $q = new QtCore;&lt;br /&gt;
 $q-&amp;gt;setVer(4.001);&lt;br /&gt;
 print $q-&amp;gt;ver(), “\n”;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате запуска скрипта должна появиться указанная нами версия 4.001.&lt;br /&gt;
&lt;br /&gt;
===Импортирование нескольких классов===&lt;br /&gt;
&lt;br /&gt;
Едва ли можно найти библиотеку, состоящую из одного класса. Когда классов немного, их можно описать в одном '''xs'''-файле, или последовать примеру модуля &amp;lt;font color=darkred&amp;gt;Search-Xapian&amp;lt;/font&amp;gt;, в котором один большой файл разбит на несколько, объединяемых командой&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 INCLUDE: подключаемый_файл.xs&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Однако главным недостатком такого подхода является необходимость подключения всех заголовочных файлов в одном месте, содержимое которых будет находиться в одной области видимости. Третий вариант, особенно удобный для такой большой библиотеки, как ''QtCore'', заключается в том, чтобы сделать каждый '''xs'''-файл относительно независимым и в каждом из них подключать только заголовочный файл, описывающий нужный класс. Это обычно делается двумя способами. Первый состоит в том, чтобы в главном '''xs'''-файле прописать импорт boot-функций всех файлов и выполнять их в boot-функции основного '''xs'''-файла, вызываемого функцией &amp;lt;font color=darkred&amp;gt;bootstrap&amp;lt;/font&amp;gt;. Примеры реализации данного способа можно увидеть в библиотеках ''perl-Glib/Gtk2'', ''Perl-RPM'' (в каждой немного по-своему). Другой способ заключается в том, чтобы все вызовы сделать из главного модуля, но уже на Perl’e. Данный вариант реализован в &amp;lt;font color=darkred&amp;gt;Win32::Gui&amp;lt;/font&amp;gt;. На мой взгляд, он более удобен и обладает большей переносимостью.&lt;br /&gt;
&lt;br /&gt;
Опишем последний вариант подробнее. Прежде всего следует удалить оставшиеся файлы предыдущей сборки, а именно: каталог '''blib''' и файлы '''Makefile''', '''pm_to_blib''', '''QtCore.bs''', '''*.c''', '''*.o'''.&lt;br /&gt;
&lt;br /&gt;
Далее настроим обработку нескольких xs-файлов, для чего в '''Makefile.PL''' раскомментируем строку&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 OBJECT           =&amp;gt; ‘$(O_FILES)’.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вследствие этого будут отрабатываться все '''xs'''-файлы, найденные в каталоге модуля (во вложенных каталогах поиск не ведется). Подключим библиотеку '''QtCore.so''', для чего в строку&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 LIBS          =&amp;gt; [‘’],&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
пропишем ее:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 LIBS          =&amp;gt; [‘-L/usr/lib -lQtCore ‘],&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Для примера импортирования нескольких классов выберем небольшой класс &amp;lt;font color=darkred&amp;gt;QSize&amp;lt;/font&amp;gt; (если у вас не установлен ''Qt4'', файл '''qsize.h''' можно найти на диске).&lt;br /&gt;
&lt;br /&gt;
Создадим файл '''QSize.xs''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 #ifdef __cplusplus&lt;br /&gt;
 extern “C” {&lt;br /&gt;
 #endif&lt;br /&gt;
 #include “EXTERN.h”&lt;br /&gt;
 #include “perl.h”&lt;br /&gt;
 #include “XSUB.h”&lt;br /&gt;
 #ifdef __cplusplus&lt;br /&gt;
 }&lt;br /&gt;
 #endif&lt;br /&gt;
 #include &amp;lt;QtCore/qsize.h&amp;gt;&lt;br /&gt;
 MODULE = QtCore::QSize       PACKAGE = QtCore::QSize&lt;br /&gt;
 =comment&lt;br /&gt;
 QSize входит в состав QtCore&lt;br /&gt;
 =cut&lt;br /&gt;
 PROTOTYPES: ENABLE&lt;br /&gt;
 QSize *&lt;br /&gt;
 QSize::new()&lt;br /&gt;
 bool&lt;br /&gt;
 QSize::isEmpty()&lt;br /&gt;
 int&lt;br /&gt;
 QSize::width()&lt;br /&gt;
 int&lt;br /&gt;
 QSize::height()&lt;br /&gt;
 void&lt;br /&gt;
 QSize::setWidth(w)&lt;br /&gt;
      int w&lt;br /&gt;
 void&lt;br /&gt;
 QSize::setHeight(h)&lt;br /&gt;
      int h&lt;br /&gt;
 void&lt;br /&gt;
 QSize::DESTROY()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Далее создадим для класса &amp;lt;font color=darkred&amp;gt;QSize&amp;lt;/font&amp;gt; собственный '''pm'''-файл '''lib/QtCore/QSize.pm'''.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 package QtCore::QSize;&lt;br /&gt;
 use 5.008;&lt;br /&gt;
 use strict;&lt;br /&gt;
 use warnings;&lt;br /&gt;
 use QtCore; # необходимо для вызыва bootstarp, находящегося в  файле QtCore&lt;br /&gt;
 QtCore::bootstrap_subpackage ‘QSize’;&lt;br /&gt;
 1;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В дальнейшем файлы '''QtCore.xs''' и '''lib/QtCore.pm''' будут нужны только для вызова bootstrap модуля '''QtCore.pm'''. Заметим, что класс в '''QtCore.xs''' можно удалить, но тогда придется добавить хотя бы одну внешнюю функцию, иначе в файле '''QtCore.c''', который создается на основе '''QtCore.xs''', не будет всех нужных объявлений. Вообще все boot-функции и объявления в них можно прописать и вручную, но вряд ли это целесообразно, если компилятор XS делает все сам. Теперь следует добавить в '''lib/QtCore.pm''' функцию, которая будет выполнять роль &amp;lt;font color=darkred&amp;gt;bootstrap&amp;lt;/font&amp;gt; для остальных модулей:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 sub bootstrap_subpackage {&lt;br /&gt;
      my($package) = @_;&lt;br /&gt;
      $package = ‘QtCore::’.$package;&lt;br /&gt;
      my $symbol = $package;&lt;br /&gt;
      $symbol =~ s/\W/_/g;&lt;br /&gt;
      no strict ‘refs’;&lt;br /&gt;
      DynaLoader::dl_install_xsub(&lt;br /&gt;
            “${package}::bootstrap”,&lt;br /&gt;
            DynaLoader::dl_find_symbol_anywhere(“boot_$symbol”)&lt;br /&gt;
      );&lt;br /&gt;
      &amp;amp;{ “${package}::bootstrap” };&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
И последний шаг в нашем примере импортирования нескольких классов. Класс следует описать в файле '''typemap''', добавив в конце&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 QSize *             O_OBJECT&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Вот теперь уже можно запустить '''perl Makefile.PL &amp;amp;&amp;amp; make''' и потестировать то, что получилось. Для проверки можно создать файл '''test/qsize.pl''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 #!/usr/bin/perl -w&lt;br /&gt;
 use blib;&lt;br /&gt;
 use QtCore::QSize;&lt;br /&gt;
 use Carp ‘croak’;&lt;br /&gt;
 my $q = new QtCore::QSize; # создать класс&lt;br /&gt;
 print “q is empty\n” if $q-&amp;gt;isEmpty();&lt;br /&gt;
 $q-&amp;gt;setWidth(2); # присвоить параметр&lt;br /&gt;
 print $q-&amp;gt;width(), “\n”; # проверить&lt;br /&gt;
 $q-&amp;gt;setHeight(3);&lt;br /&gt;
 print “q isn’t empty\n” unless $q-&amp;gt;isEmpty();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Использование нескольких конструкторов===&lt;br /&gt;
&lt;br /&gt;
Класс &amp;lt;font color=darkred&amp;gt;QSize&amp;lt;/font&amp;gt; содержит два конструктора, а компилятор XS знает только про new. Поэтому второй конструктор мы реализуем сами. Чтобы увидеть, что для этого надо, достаточно посмотреть в файл '''QSize.c''', автоматически сгенерированный компилятором XS из файла '''QSize.xs''':&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 char *      CLASS = (char *)SvPV_nolen(ST(0));&lt;br /&gt;
 QSize *      RETVAL;&lt;br /&gt;
 RETVAL = new QSize();&lt;br /&gt;
 ST(0) = sv_newmortal();&lt;br /&gt;
 sv_setref_pv( ST(0), CLASS, (void*)RETVAL );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Иными словами, благодаря &amp;lt;font color=darkred&amp;gt;QSize::&amp;lt;/font&amp;gt;, расположенному перед конструктором &amp;lt;font color=darkred&amp;gt;new&amp;lt;/font&amp;gt;, в функцию передается строковый параметр &amp;lt;font color=darkred&amp;gt;CLASS&amp;lt;/font&amp;gt; с названием класса, после чего создается объект и используется &amp;lt;font color=darkred&amp;gt;bless&amp;lt;/font&amp;gt; для полученной ссылки. Для примера импорта конструктора в '''QSize.xs''' создадим конструктор &amp;lt;font color=darkred&amp;gt;new1&amp;lt;/font&amp;gt; с явным указанием компилятору на код и возвращаемый параметр:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 QSize *&lt;br /&gt;
 new1(CLASS)&lt;br /&gt;
      char * CLASS&lt;br /&gt;
      CODE:&lt;br /&gt;
            RETVAL = new QSize();&lt;br /&gt;
      OUTPUT:&lt;br /&gt;
      RETVAL&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Теперь запустим ''make''. Получный в '''QSize.c''' код для &amp;lt;font color=darkred&amp;gt;new1&amp;lt;/font&amp;gt; будет идентичен автоматически созданному коду для конструктора &amp;lt;font color=darkred&amp;gt;new&amp;lt;/font&amp;gt;. Однако появятся две пометки о том, что код взят из '''QSize.xs'''. Аналогично создадим второй конструктор, но уже с параметрами инициализации:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 QSize *&lt;br /&gt;
 new2(CLASS, w, h);&lt;br /&gt;
      int w&lt;br /&gt;
      int h&lt;br /&gt;
      char * CLASS&lt;br /&gt;
      CODE:&lt;br /&gt;
            RETVAL = new QSize(w, h);&lt;br /&gt;
      OUTPUT:&lt;br /&gt;
            RETVAL&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Заметим, что в Perl’е удобнее было бы использовать идентификатор &amp;lt;font color=darkred&amp;gt;new&amp;lt;/font&amp;gt; для вызова любого конструктора, не различая их по номерам.&lt;br /&gt;
Для реализации этой идеи удалим из '''QSize.xs''' вызов &amp;lt;font color=darkred&amp;gt;QSize::new()&amp;lt;/font&amp;gt;, после чего добавим в '''lib/QtCore/QSize.pm''' функцию с таким же названием. В зависимости от содержимого, она сама будет выбирать, что ей вызвать. При неверном количестве параметров функция выведет сообщение об ошибке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 sub new {&lt;br /&gt;
      return new1($_[0]) if ( scalar(@_) == 1 );&lt;br /&gt;
      return new2($_[0], $_[1], $_[2]) if ( scalar(@_) == 3 );&lt;br /&gt;
      croak(“ожидалось 0 или 2 параметра\n”);&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Далее дайте команду ''make'' и проверьте, как все работает, для чего добавьте в '''test/qsize.pl''' строку&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 my $w = QtCore::QSize-&amp;gt;new(5,6);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
===Сложение классов ( operator+ )===&lt;br /&gt;
&lt;br /&gt;
Если в исходном классе, написанном на С++, содержатся операторы «арифметических» и «логических» действий c классами, то данные&lt;br /&gt;
функции желательно импортировать в Perl.&lt;br /&gt;
&lt;br /&gt;
Сначала рассмотрим, что добавить в '''QSize.xs''' для &lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 QSize &amp;amp;operator+=(const QSize &amp;amp;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Оператор возвращает тот же класс, к которому осуществляется прибавление, поэтому возвратить &amp;lt;font color=darkred&amp;gt;QSize&amp;lt;/font&amp;gt; можно и в функции на Perl’e. Поскольку Perl по своей сути работает только с указателями, то перед передачей функции прибавляемого класса &amp;lt;font color=darkred&amp;gt;otherSize&amp;lt;/font&amp;gt; его (указатель) следует разыменовать:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 void&lt;br /&gt;
 QSize::operator_plus_eq(otherSize)&lt;br /&gt;
       QSize * otherSize&lt;br /&gt;
       CODE:&lt;br /&gt;
              THIS-&amp;gt;operator+= (*otherSize);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Или, например, другой оператор:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 friend inline const QSize operator+(const QSize &amp;amp;, const QSize &amp;amp;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Несмотря на то, что фунция &amp;lt;font color=darkred&amp;gt;operator+&amp;lt;/font&amp;gt; не является внутренней для &amp;lt;font color=darkred&amp;gt;QSize&amp;lt;/font&amp;gt;, это не мешает получить указатель на первый класс указанным выше способом. В то же время &amp;lt;font color=darkred&amp;gt;operator+&amp;lt;/font&amp;gt; возвращает новый объект &amp;lt;font color=darkred&amp;gt;QSize&amp;lt;/font&amp;gt;, который будет жить только в пределах С-функции. Нам же необходимо вернуть указатель на новый объект &amp;lt;font color=darkred&amp;gt;QSize&amp;lt;/font&amp;gt;. Поэтому создадим новый экземпляр класса &amp;lt;font color=darkred&amp;gt;QSize&amp;lt;/font&amp;gt; и присвоим ему результат. Класс &amp;lt;font color=darkred&amp;gt;QSize&amp;lt;/font&amp;gt; простой, поэтому конструктор копий создается компилятором автоматически.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 QSize *&lt;br /&gt;
 QSize::operator_plus(qsize2)&lt;br /&gt;
       QSize * qsize2&lt;br /&gt;
       PREINIT:&lt;br /&gt;
       char * CLASS = “QtCore::QSize”;&lt;br /&gt;
       CODE:&lt;br /&gt;
              RETVAL = new QSize();&lt;br /&gt;
              *RETVAL = (operator+ ( *THIS, *qsize2 ));&lt;br /&gt;
       OUTPUT:&lt;br /&gt;
              RETVAL&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В файле '''lib/QtCore/QSize.pm''' следует сделать оболочку для данных функций, используя &amp;lt;font color=darkred&amp;gt;overload&amp;lt;/font&amp;gt; (подробности использования &amp;lt;font color=darkred&amp;gt;overload&amp;lt;/font&amp;gt; смотрите в '''perldoc''' или «Программировании на Perl» &amp;lt;font color=darkblue&amp;gt;[5, стр. 397]&amp;lt;/font&amp;gt;):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 use overload&lt;br /&gt;
       ‘+’ =&amp;gt; \&amp;amp;_plus,&lt;br /&gt;
       ‘+=’ =&amp;gt; \&amp;amp;_plus_eq,&lt;br /&gt;
       ‘””’ =&amp;gt; sub { $_[0] };&lt;br /&gt;
 sub _plus_eq {&lt;br /&gt;
       unless ( ref($_[1]) ) {&lt;br /&gt;
              croak(“need QSize += QSize\n”);&lt;br /&gt;
              return;&lt;br /&gt;
       }&lt;br /&gt;
       operator_plus_eq($_[0], $_[1]);&lt;br /&gt;
       return $_[0]; # возвращается указатель на тот же экземпляр&lt;br /&gt;
 класса&lt;br /&gt;
 }&lt;br /&gt;
 sub _plus {&lt;br /&gt;
       if ( ref($_[0]) and ref($_[1]) ) {&lt;br /&gt;
              return operator_plus($_[0], $_[1]);&lt;br /&gt;
       }&lt;br /&gt;
       croak(“Need QSize1 = QSize2 + QSize3\n”);&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В заключение осталось проверить работоспособность операторов. Добавьте в '''test/qsize.pl''' такие строки:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 $w += $q;&lt;br /&gt;
 print “w (h, w) == “, $w-&amp;gt;height(), “ “, $w-&amp;gt;width(), “\n”;&lt;br /&gt;
 my $e = $w + $q;&lt;br /&gt;
 print “e (h, w) == “, $e-&amp;gt;height(), “ “, $e-&amp;gt;width(), “\n”;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
И, запустив, убедитесь, что это работает.&lt;br /&gt;
&lt;br /&gt;
===Особенности использования enum===&lt;br /&gt;
&lt;br /&gt;
Работа с &amp;lt;font color=darkred&amp;gt;enum&amp;lt;/font&amp;gt; предусмотрена в Perl XS, однако с C++ появляется одна неприятность. В время обработки '''xs'''-файла компилятором XS обращения в другие классы за определенными в них enum, как, например, &amp;lt;font color=darkred&amp;gt;Qt::AspectRatioMode&amp;lt;/font&amp;gt;, в с-файле &amp;lt;font color=darkred&amp;gt;Qt::AspectRatioMode&amp;lt;/font&amp;gt; превращается в &amp;lt;font color=darkred&amp;gt;Qt__AspectRatioMode&amp;lt;/font&amp;gt;, и выдается ошибка компилятора о несуществующем типе. К сожалению, нет никакой возможности избежать этого преобразования, ибо таким способом создаются все функции с целью&lt;br /&gt;
не допустить дублирования названий функций с другими классами. Чтобы компилятор правильно увидел используемый нами enum, переопределим его в исходный облик. В C-части '''xs'''-файла после подключения '''qsize.h''' добавим:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 #define Qt__AspectRatioMode Qt::AspectRatioMode&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Теперь можно описать функцию с этим типом данных:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 void&lt;br /&gt;
 QSize::scale(w, h, mode)&lt;br /&gt;
       int w&lt;br /&gt;
       int h&lt;br /&gt;
       Qt::AspectRatioMode mode&lt;br /&gt;
       CODE:&lt;br /&gt;
             THIS-&amp;gt;scale(w, h, mode);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Не забудьте добавить в '''typemap''' новый тип данных:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 Qt::AspectRatioMode              T_ENUM&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Чтобы не запоминать числовые значения всех enum-параметров, добавим модуль '''lib/Qt.pm''' со всеми значениями &amp;lt;font color=darkred&amp;gt;AspectRatioMode&amp;lt;/font&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 package Qt;&lt;br /&gt;
 # enum AspectRatioMode&lt;br /&gt;
 use constant IgnoreAspectRatio =&amp;gt; 0;&lt;br /&gt;
 use constant KeepAspectRatio =&amp;gt; 1;&lt;br /&gt;
 use constant KeepAspectRatioByExpanding =&amp;gt; 2;&lt;br /&gt;
 1;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
После добавления или удаления любого файла, следует полностью очистить библиотеку, удалив каталог '''blib''', файлы '''*.c''', '''*.o''' и т.д. После данных манипуляций и выполнения команд '''perl Makefile.PL &amp;amp;&amp;amp; make''' можно тестировать программу. Для этого после &amp;lt;font color=darkred&amp;gt;use blib&amp;lt;/font&amp;gt; в файле '''qsize.pl''' следует добавить&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 use Qt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
а также дописать новую функцию в конце этого файла:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 $e-&amp;gt;scale(20, 20, Qt::IgnoreAspectRatio);&lt;br /&gt;
 print “scale e (h, w) == “, $e-&amp;gt;height(), “ “, $e-&amp;gt;width(), “\n”;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Взаимодействие с STL или ее аналогами===&lt;br /&gt;
&lt;br /&gt;
В Perl’e STL практически не нужна, поскольку большинство возможностей STL уже поддерживаются массивами и хэшами самого языка. Поэтому рассмотрим только передачу данных из шаблона &amp;lt;font color=darkred&amp;gt;list&amp;lt;/font&amp;gt; в массив Perl’a и обратно. Библиотека ''Qt4'' инкапсулирует в себе STL, добавляя некоторые возможности. Мы подробно рассмотрим работу с шаблоном &amp;lt;font color=darkred&amp;gt;QList&amp;lt;/font&amp;gt;, ибо методы некоторых классов возвращают списки классов, используя именно его. Для получения массива обратимся к классу &amp;lt;font color=darkred&amp;gt;QbyteArray&amp;lt;/font&amp;gt;. В нем есть такой конструктор:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 QList&amp;lt;QByteArray&amp;gt; split(char sep) const;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В файле '''QByteArray.xs''' перед использованием шаблонов STL необходимо убрать определения &amp;lt;font color=darkred&amp;gt;do_open&amp;lt;/font&amp;gt; и &amp;lt;font color=darkred&amp;gt;do_close&amp;lt;/font&amp;gt;, иначе они начнут конфликтовать с аналогичными из Perl’a.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
 #undef do_open&lt;br /&gt;
 #undef do_close&lt;br /&gt;
 #include &amp;lt;QtCore/qlist.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;QtCore/qbytearray.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
 AV *&lt;br /&gt;
 QByteArray::_split(c)&lt;br /&gt;
       char c&lt;br /&gt;
       CODE:&lt;br /&gt;
             RETVAL = newAV();&lt;br /&gt;
             QList&amp;lt;QByteArray&amp;gt; lba = THIS-&amp;gt;split(c);&lt;br /&gt;
             for ( int i = 0 ; i &amp;lt; lba.size() ; ++i ) {&lt;br /&gt;
                   QByteArray * ba = new QByteArray();&lt;br /&gt;
                   *ba = lba.at(i);&lt;br /&gt;
                   SV * rv = newSV(0);&lt;br /&gt;
                   sv_setref_pv( rv, “QtCore::QByteArray”, (void *)ba );&lt;br /&gt;
                   av_push(RETVAL, rv);&lt;br /&gt;
             };&lt;br /&gt;
       OUTPUT:&lt;br /&gt;
             RETVAL&lt;br /&gt;
       CLEANUP:&lt;br /&gt;
             SvREFCNT_dec( RETVAL );&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Иными словами, в описании &amp;lt;font color=darkred&amp;gt;_split&amp;lt;/font&amp;gt; создается анонимный массив,  указатель на который будет передан в программу. Затем вызывается функция &amp;lt;font color=darkred&amp;gt;split&amp;lt;/font&amp;gt; класса на C++, которая возвращает список объектов &amp;lt;font color=darkred&amp;gt;QByteArray&amp;lt;/font&amp;gt;. Этот список обходится в цикле, в котором по одному указателю на объект заносится в массив &amp;lt;font color=darkred&amp;gt;RETVAL&amp;lt;/font&amp;gt;. Поскольку массив принимает только тип данных &amp;lt;font color=darkred&amp;gt;SV*&amp;lt;/font&amp;gt;, то на каждой итерации цикла создается новая переменная. Затем в нее копируется ссылка на объект из списка, приведенная к типу данных Perl функцией &amp;lt;font color=darkred&amp;gt;sv_setref_pv&amp;lt;/font&amp;gt;. Подробно работа с массивами в Perl XS описана в &amp;lt;font color=darkred&amp;gt;perlguts&amp;lt;/font&amp;gt;, а примеры использования массива со строками можно посмотреть в “''XS Cookbook''” &amp;lt;font color=darkblue&amp;gt;[2]&amp;lt;/font&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Следующий шаг состоит в добавлении в '''typemap''' нового класса&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt; &lt;br /&gt;
 QByteArray *                O_OBJECT&lt;br /&gt;
&amp;lt;/sorce&amp;gt;&lt;br /&gt;
и создании для этого класса модуля '''lib/QtCore/QByteArray.pm'''. Функция &amp;lt;font color=darkred&amp;gt;_split&amp;lt;/font&amp;gt; возвращает указатель на массив, однако в программе удобнее пользоваться обычным массивом. С этой целью напишем простейшую оболочку для этой функции. Кроме того, в Perl’e есть своя функция &amp;lt;font color=darkred&amp;gt;split&amp;lt;/font&amp;gt;, поэтому ее надо переопределить в пакете, используя &amp;lt;font color=darkred&amp;gt;use subs&amp;lt;/font&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt; &lt;br /&gt;
 package QtCore::QByteArray;&lt;br /&gt;
  use 5.008;&lt;br /&gt;
  use strict;&lt;br /&gt;
  use warnings;&lt;br /&gt;
  use Carp qw/carp croak/;&lt;br /&gt;
  use QtCore; # bootstraps QtCore.xs&lt;br /&gt;
  QtCore::bootstrap_subpackage ‘QByteArray’;&lt;br /&gt;
  use subs qw(split);&lt;br /&gt;
  sub split {&lt;br /&gt;
        croak(“split: нет разделителя\n”) unless $_[1];&lt;br /&gt;
        return @{ _split($_[0], $_[1]) };&lt;br /&gt;
  }&lt;br /&gt;
 1;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Пересоберите пакет и протестируйте его (файл '''test/qbytearray.pl''').&lt;br /&gt;
&lt;br /&gt;
Аналогичным способом массив превращается в шаблон &amp;lt;font color=darkred&amp;gt;QList&amp;lt;/font&amp;gt;. Для примера приведем конструктор класса &amp;lt;font color=darkred&amp;gt;QStringList&amp;lt;/font&amp;gt;, получающий для инициализации массив объектов &amp;lt;font color=darkred&amp;gt;QString&amp;lt;/font&amp;gt;. В файле '''QtCore/qstrinlist.h''' конструктор объявлен как&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 inline QStringList(const QStringList &amp;amp;l) : QList&amp;lt;QString&amp;gt;(l) { }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В '''xs'''-файле для него необходимо создать класс &amp;lt;font color=darkred&amp;gt;QList&amp;lt;QString&amp;gt;&amp;lt;/font&amp;gt; и заполнить его объектами &amp;lt;font color=darkred&amp;gt;QString&amp;lt;/font&amp;gt;, полученными из массива. av является указателем на копию этого массива. Копия используется, поскольку функция &amp;lt;font color=darkred&amp;gt;av_pop()&amp;lt;/font&amp;gt; удаляет из массива считанные элементы.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 QStringList *&lt;br /&gt;
 new3(CLASS, av)&lt;br /&gt;
       char * CLASS&lt;br /&gt;
       AV * av&lt;br /&gt;
       CODE:&lt;br /&gt;
            QList&amp;lt;QString&amp;gt; qls;&lt;br /&gt;
            while ( av_len(av) &amp;gt; -1 ) {&lt;br /&gt;
                 SV * rv = av_pop(av);&lt;br /&gt;
                 QString * str = (QString *)SvIV((SV*)SvRV( rv ));&lt;br /&gt;
                 qls &amp;lt;&amp;lt; *str;&lt;br /&gt;
            }&lt;br /&gt;
            RETVAL = new QStringList(qls);&lt;br /&gt;
       OUTPUT:&lt;br /&gt;
            RETVAL&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Описание типа данных, отсутствующего в typemap.xs и perlobject.map===&lt;br /&gt;
&lt;br /&gt;
В том случае, если нужно добавить новый тип данных, необходимо описать, как компилятору работать с ним, т.е. читать из него данные и записывать. Данная тема описана в документации Perl, но для полноты картины приведем пример, иллюстрирующий работу с отсутствующим в С типом &amp;lt;font color=darkred&amp;gt;string&amp;lt;/font&amp;gt;. Для этого типа в '''typemap''' следует добавить:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
 string           STRING&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Ниже в разделах &amp;lt;font color=darkred&amp;gt;INPUT&amp;lt;/font&amp;gt; и &amp;lt;font color=darkred&amp;gt;OUTPUT&amp;lt;/font&amp;gt; необходимо описать, как перевести &amp;lt;font color=darkred&amp;gt;string&amp;lt;/font&amp;gt; из внутреннего типа данных Perl’а (переменная &amp;lt;font color=darkred&amp;gt;$arg&amp;lt;/font&amp;gt;) в C++ (переменная &amp;lt;font color=darkred&amp;gt;$var&amp;lt;/font&amp;gt;) и обратно. &lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt; &lt;br /&gt;
 INPUT&lt;br /&gt;
 STRING&lt;br /&gt;
 {&lt;br /&gt;
       STRLEN len;&lt;br /&gt;
       const char * tmp = SvPV($arg, len);&lt;br /&gt;
       $var.assign(tmp, len);&lt;br /&gt;
       }&lt;br /&gt;
 OUTPUT&lt;br /&gt;
 STRING&lt;br /&gt;
       sv_setpvn((SV*)$arg, (char *) ($var.data()), ($var.size()));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Таким образом, в данной статье были рассмотрены все основные варианты использования C++ и Perl XS. За ее пределами остались только прямое использование шаблонных классов (но, как было указано выше, использовать их нецелесообразно, т. к. STL покрывается возможностями самого Perl’a) и использование lvalue-функций из классов С++ в Perl’e (когда разрабатывался Perl XS для 5-й версии, lvalue изначально не был реализован и в самом Perl5, а более поздних описаний расширений Perl XS на данный момент, по моим сведениям, не существует).&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
&lt;br /&gt;
#Документация Perl (perlxs, perlxstut, perlguts).&lt;br /&gt;
#Dean’s Extension-Building Cookbook in two parts. Part A: http://www.cpan.org/authors/Dean_Roehrich/CookBookA-19960430.tar.gz.&lt;br /&gt;
#Dean’s Extension-Building Cookbook in two parts. Part B: http://www.cpan.org/authors/Dean_Roehrich/CookBookB-19960430.tar.gz.&lt;br /&gt;
#http://www.cpan.org/authors/Dean_Roehrich/perlobject.map-19960302.gz.&lt;br /&gt;
#John Keiser. Gluing C++ And Perl Together. – 2001. – http://www.johnkeiser.com/perl-xs-c++.html.&lt;br /&gt;
#Уолл Л., Кристиансен Т., Орвант Д. Программирование на Perl. – СПб.: Символ-плюс, 2005. – 1152 с.&lt;br /&gt;
#http://search.cpan.org/~nwclark/perl-5.8.8/ext/XS/Typemap/Typemap.xs.&lt;/div&gt;</summary>
		<author><name>Belogorie</name></author>	</entry>

	</feed>