XSLoader
СОДЕРЖАНИЕ
- НАЗВАНИЕ
- ВЕРСИЯ
- СИНОПСИС
- ОПИСАНИЕ
- Порядок инициализации: early load()
- ДИАГНОСТИКА
- ОГРАНИЧЕНИЯ
- ИЗВЕСТНЫЕ ОШИБКИ
- ОШИБКИ
- СМОТРИТЕ ТАКЖЕ
- АВТОРЫ
- АВТОРСКИЕ ПРАВА И ЛИЦЕНЗИЯ
НАЗВАНИЕ
XSLoader - Динамическая загрузка библиотек C в код Perl
ВЕРСИЯ
Версия 0.30
СИНОПСИС
package YourPackage;
require XSLoader;
XSLoader::load(__PACKAGE__, $VERSION); ОПИСАНИЕ
Этот модуль определяет стандартный упрощенный интерфейс к механизмам динамической загрузки, доступным на многих платформах. Его основная цель - реализовать быструю автоматическую динамическую загрузку модулей Perl.
Для более сложного интерфейса см. DynaLoader. Многие (большинство) функции DynaLoader не реализованы в XSLoader, например, dl_load_flags, не поддерживаемое XSLoader.
Миграция с DynaLoader
Типичный модуль, использующий DynaLoader, начинается так:
package YourPackage;
require DynaLoader;
our @ISA = qw( OnePackage OtherPackage DynaLoader );
our $VERSION = '0.01';
__PACKAGE__->bootstrap($VERSION); Измените это на
package YourPackage;
use XSLoader;
our @ISA = qw( OnePackage OtherPackage );
our $VERSION = '0.01';
XSLoader::load(__PACKAGE__, $VERSION); Другими словами: замените require DynaLoader на use XSLoader, удалите DynaLoader из @ISA, замените bootstrap на XSLoader::load. Не забудьте указать имя вашего пакета в строке XSLoader::load, и добавьте запятую (,) перед аргументами ($VERSION выше).
Конечно, если @ISA содержало только DynaLoader, нет необходимости иметь присваивание @ISA; более того, если вместо our используется более обратная совместимая
use vars qw($VERSION @ISA); можно удалить ссылку на @ISA вместе с присваиванием @ISA.
Если $VERSION не было указано в строке bootstrap, последняя строка становится
XSLoader::load(__PACKAGE__); в котором случае это можно упростить до
XSLoader::load(); поскольку load будет использовать caller для определения пакета.
Обратно совместимая шаблонная структура
Если вы хотите испечь свой пирог и съесть его, вам нужна более сложная шаблонная структура.
package YourPackage;
our @ISA = qw( OnePackage OtherPackage );
our $VERSION = '0.01';
eval {
require XSLoader;
XSLoader::load(__PACKAGE__, $VERSION);
1;
} or do {
require DynaLoader;
push @ISA, 'DynaLoader';
__PACKAGE__->bootstrap($VERSION);
}; Скобки вокруг аргументов XSLoader::load() необходимы, поскольку мы заменили use XSLoader на require, поэтому компилятор не знает, что функция XSLoader::load() присутствует.
Эта шаблонная структура использует XSLoader с низкой нагрузкой, если он присутствует; если она используется с антикварным Perl, у которого нет XSLoader, она возвращается к использованию DynaLoader.
Порядок инициализации: early load()
Пропустите этот раздел, если функции XSUB должны вызываться только из других модулей; читайте его только если вы вызываете свои функции XSUB из кода в вашем модуле или имеете раздел BOOT: в вашем файле XS (см. "Ключевое слово BOOT: в perlxs). Описанное здесь относится также к интерфейсу DynaLoader.
Достаточно сложный модуль, использующий XS, будет иметь как код Perl (определенный в YourPackage.pm), так и код XS (определенный в YourPackage.xs). Если этот код Perl вызывает этот код XS, и/или этот код XS вызывает код Perl, нужно быть осторожным с порядком инициализации.
Вызов XSLoader::load() (или bootstrap()) вызывает код загрузки модуля. Для модулей, созданных с помощью xsubpp (почти все модули), это имеет три побочных эффекта:
-
Проводится проверка целостности, чтобы убедиться, что версии .pm и скомпилированной части .xs совместимы. Если было указано
$VERSION, оно используется для проверки. Если не указано, оно по умолчанию равно$XS_VERSION // $VERSION(в пространстве имен модуля) -
Функции XSUB становятся доступными из Perl
-
Если в файле .xs был раздел
BOOT:, код в нем вызывается.
Следовательно, если код в файле .pm вызывает эти функции XSUB, удобно иметь функции XSUB установленные до определения кода Perl; например, это делает прототипы функций XSUB видимыми для этого кода Perl. В противном случае, если раздел BOOT: вызывает функции Perl (или использует переменные Perl), определенные в файле .pm, они должны быть определены до вызова XSLoader::load() (или bootstrap()).
Так как первый случай встречается гораздо чаще, имеет смысл переписать шаблонную структуру как
package YourPackage;
use XSLoader;
our ($VERSION, @ISA);
BEGIN {
@ISA = qw( OnePackage OtherPackage );
$VERSION = '0.01';
# Put Perl code used in the BOOT: section here
XSLoader::load(__PACKAGE__, $VERSION);
}
# Put Perl code making calls into XSUBs here Самый сложный случай
Если взаимозависимость вашего раздела BOOT: и кода Perl сложнее (например, раздел BOOT: вызывает функции Perl, которые вызывают функции XSUB с прототипами), удалите раздел BOOT: полностью. Замените его функцией onBOOT() и вызовите ее так:
package YourPackage;
use XSLoader;
our ($VERSION, @ISA);
BEGIN {
@ISA = qw( OnePackage OtherPackage );
$VERSION = '0.01';
XSLoader::load(__PACKAGE__, $VERSION);
}
# Put Perl code used in onBOOT() function here; calls to XSUBs are
# prototype-checked.
onBOOT;
# Put Perl initialization code assuming that XS is initialized here ДИАГНОСТИКА
-
Can't find '%s' symbol in %s -
(F) Символ загрузки не был найден в модуле расширения.
-
Can't load '%s' for module %s: %s -
(F) Загрузка или инициализация модуля расширения не удались. Следуйте за подробной ошибкой.
-
Undefined symbols present after loading %s: %s -
(W) Как показывает сообщение, некоторые символы остаются неопределенными, хотя модуль расширения был правильно загружен и инициализирован. Список неопределенных символов следует ниже.
ОГРАНИЧЕНИЯ
Чтобы свести к минимуму накладные расходы, проверяется только одно возможное местоположение, чтобы найти DLL расширения (это местоположение, куда make install поместил бы DLL). Если не найдено, поиск DLL прозрачно делегируется DynaLoader, который ищет DLL по списку @INC.
В частности, это относится к структуре @INC используемой для тестирования не установленных расширений. Это означает, что запуск не установленных расширений может иметь гораздо больше накладных расходов, чем запуск тех же расширений после make install.
ИЗВЕСТНЫЕ ОШИБКИ
Новый упрощенный способ вызова XSLoader::load() без аргументов вообще не работает в Perl 5.8.4 и 5.8.5.
ОШИБКИ
Пожалуйста, сообщите об ошибках или пожеланиях по функциям с помощью утилиты perlbug(1).
СМОТРИТЕ ТАКЖЕ
АВТОРЫ
Илья Захаревич изначально извлек XSLoader из DynaLoader.
Версия CPAN в настоящее время поддерживается Себастьен Апергис-Трамони <sebastien@aperghis.net>.
Предыдущий ответственный был Майкл Дж Шверн <schwern@pobox.com>.
АВТОРСКИЕ ПРАВА И ЛИЦЕНЗИЯ
Авторские права (C) 1990-2011 гг. Ларри Уоллом и другими.
Эта программа является свободной программой; вы можете перераспределять её и/или изменять её в соответствии с теми же условиями, что и сам Perl.
© 1993–2020 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.28.3/XSLoader