XSLoader
СОДЕРЖАНИЕ
- ИМЯ
- ВЕРСИЯ
- СИНОПСИС
- ОПИСАНИЕ
- Порядок инициализации: раннее load()
- ДИАГНОСТИКА
- ОГРАНИЧЕНИЯ
- ИЗВЕСТНЫЕ ОШИБКИ
- ОШИБКИ
- СМОТРИ ТАКЖЕ
- АВТОРЫ
- АВТОРСКИЕ ПРАВА И ЛИЦЕНЗИЯ
ИМЯ
XSLoader — динамическая загрузка библиотек C в код Perl
ВЕРСИЯ
Версия 0.31
СИНОПСИС
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.
Если в строке bootstrap не был указан $VERSION, последняя строка становится
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.
Порядок инициализации: раннее load()
Пропустите этот раздел, если функции XSUB должны вызываться только из других модулей; читайте его только если вы вызываете свои XSUB из кода в вашем модуле или имеете раздел BOOT: в вашем файле XS (см. "The BOOT: Keyword" в 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
-
если раздел
BOOT:присутствовал в файле .xs, код там вызывается.
Следовательно, если код в файле .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 в настоящее время поддерживается Sébastien Aperghis-Tramoni <sebastien@aperghis.net>.
Предыдущий основной разработчик был Michael G Schwern <schwern@pobox.com>.
АВТОРСКИЕ ПРАВА И ЛИЦЕНЗИЯ
Авторские права (C) 1990-2011 Larry Wall и др.
Эта программа — свободное программное обеспечение; вы можете перераспределять её и/или изменять её на тех же условиях, что и Perl сам по себе.
© 1993–2021 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.36.0/XSLoader