Spec-Zone.ru › Perl 5.38

DynaLoader

СОДЕРЖАНИЕ

  • ИМЯ
  • СИНТАКСИС
  • ОПИСАНИЕ
  • АВТОР

ИМЯ

DynaLoader — Динамическая загрузка библиотек C в Perl-код

СИНТАКСИС

package YourPackage;
require DynaLoader;
@ISA = qw(... DynaLoader ...);
__PACKAGE__->bootstrap;

# optional method for 'global' loading
sub dl_load_flags { 0x01 }     

ОПИСАНИЕ

Этот документ определяет стандартный универсальный интерфейс к механизмам динамической компоновки, доступным на многих платформах. Его основная цель — реализовать автоматическую динамическую загрузку Perl-модулей.

Этот документ служит как спецификацией для всех, кто хочет реализовать DynaLoader для новой платформы, так и руководством для тех, кто хочет использовать DynaLoader напрямую в приложении.

DynaLoader разработан как очень простой высокоуровневый интерфейс, который достаточно универсален для покрытия требований SunOS, HP-UX, Linux, VMS и других платформ.

Также надеемся, что интерфейс будет удовлетворять потребности OS/2, NT и т.д., а также позволит реализовать псевдодинамическую компоновку (используя ld -A во время выполнения).

Необходимо подчеркнуть, что сам DynaLoader практически бесполезен для доступа к библиотекам, не являющимся Perl, поскольку он предоставляет почти никакой «клей» Perl-C. Например, нет механизма для вызова функции C-библиотеки или передачи аргументов. Модуль C::DynaLib доступен на сайтах CPAN, который выполняет эту функцию для некоторых распространённых типов систем. А с 2000 года также есть модуль Inline::C, который позволяет вам писать Perl-подпрограммы на C. Также доступен на вашем локальном сайте CPAN.

Резюме интерфейса DynaLoader

@dl_library_path
@dl_resolve_using
@dl_require_symbols
$dl_debug
$dl_dlext
@dl_librefs
@dl_modules
@dl_shared_objects
                                                Implemented in:
bootstrap($modulename)                               Perl
@filepaths = dl_findfile(@names)                     Perl
$flags = $modulename->dl_load_flags                  Perl
$symref  = dl_find_symbol_anywhere($symbol)          Perl

$libref  = dl_load_file($filename, $flags)           C
$status  = dl_unload_file($libref)                   C
$symref  = dl_find_symbol($libref, $symbol)          C
@symbols = dl_undef_symbols()                        C
dl_install_xsub($name, $symref [, $filename])        C
$message = dl_error                                  C
@dl_library_path

Стандартный/по умолчанию список каталогов, в которых функция dl_findfile() будет искать библиотеки и т. д. Каталоги просматриваются в порядке: $dl_library_path[0], [1] и т. д.

@dl_library_path инициализируется списком «обычных» каталогов (/usr/lib и т. д.), определяемых Configure ($Config{'libpth'}). Это должно обеспечить переносимость на широкий спектр платформ.

@dl_library_path также должен быть инициализирован любыми другими каталогами, которые могут быть определены из среды во время выполнения (например, LD_LIBRARY_PATH для SunOS).

После инициализации @dl_library_path может быть изменён приложением с помощью push и unshift перед вызовом dl_findfile(). Unshift может быть использован для добавления каталогов в начало порядка поиска, чтобы сэкономить время поиска или переопределить библиотеки с одинаковыми именами в «обычных» каталогах.

Функция загрузки, которую вызывает dl_load_file(), может потребовать абсолютный путь. Функция dl_findfile() и @dl_library_path могут использоваться для поиска и возвращения абсолютного пути к библиотеке/объекту, который вы хотите загрузить.

@dl_resolve_using

Список дополнительных библиотек или других общих объектов, которые могут использоваться для разрешения любых неопределённых символов, которые могут быть сгенерированы более поздним вызовом load_file().

Это необходимо только на некоторых платформах, которые не обрабатывают зависимые библиотеки автоматически. Например, библиотека расширений Socket Perl (auto/Socket/Socket.so) содержит ссылки на многие функции сокетов, которые должны быть разрешены при её загрузке. Большинство платформ автоматически знают, где найти зависимую библиотеку (например, /usr/lib/libsocket.so). Некоторым платформам нужно явно указать расположение зависимой библиотеки. Используйте @dl_resolve_using для этого.

Пример использования:

@dl_resolve_using = dl_findfile('-lsocket');
@dl_require_symbols

Список одного или нескольких имён символов, которые находятся в файле библиотеки/объекта для динамической загрузки. Это необходимо только на некоторых платформах.

@dl_librefs

Массив обработчиков, возвращённых успешными вызовами dl_load_file(), выполненными bootstrap, в порядке их загрузки. Может использоваться с dl_find_symbol() для поиска символа в любом из загруженных файлов.

@dl_modules

Массив имён модулей (пакетов), которые были bootstrap'ed.

@dl_shared_objects

Массив имён файлов общих объектов, которые были загружены.

dl_error()

Синтаксис:

$message = dl_error();

Текст сообщения об ошибке от последней не удавшейся функции DynaLoader. Обратите внимание, что, подобно errno в unix, успешный вызов функции не сбрасывает это сообщение.

Реализации должны обнаруживать ошибку сразу же после её возникновения в любой из других функций и сохранять соответствующее сообщение для последующего извлечения. Это позволит избежать проблем на некоторых платформах (например, SunOS), где сообщение об ошибке очень временное (например, dlerror()).

$dl_debug

Внутренние сообщения отладки включены, когда $dl_debug установлен в true. В настоящее время установка $dl_debug влияет только на перловскую сторону DynaLoader. Эти сообщения должны помочь разработчику приложений в решении любых проблем, связанных с использованием DynaLoader.

$dl_debug устанавливается в $ENV{'PERL_DL_DEBUG'} при определении.

Для разработчика/портёра DynaLoader существует аналогичная переменная отладки, добавленная в C-код (см. dlutils.c) и включенная, если Perl был скомпилирован с флагом -DDEBUGGING. Её также можно задать через переменную среды PERL_DL_DEBUG. Установите в 1 для минимальной информации или выше для большего количества.

$dl_dlext

При указании (локализации) в файле .pm модуля, указывает расширение, которое будет иметь загружаемый объект модуля. Например:

local $DynaLoader::dl_dlext = 'unusual_ext';

указывает, что загружаемый объект модуля имеет расширение unusual_ext вместо более привычного $Config{dlext}. ПРИМЕЧАНИЕ: это также требует, чтобы Makefile.PL модуля указал (в WriteMakefile()):

DLEXT => 'unusual_ext',
dl_findfile()

Синтаксис:

@filepaths = dl_findfile(@names)

Определить полные пути (включая суффикс файла) одного или нескольких загружаемых файлов, зная их общие имена и, необязательно, один или несколько каталогов. По умолчанию ищет каталоги в @dl_library_path и возвращает пустой список, если файлы не найдены.

Имена могут быть указаны в различных независимых от платформы форматах. Любые имена в форме -lname преобразуются в libname.*, где .* — соответствующий суффикс для платформы.

Если имя ещё не имеет подходящего префикса и/или суффикса, соответствующий файл будет искаться путём перебора комбинаций префикса и суффикса, соответствующих платформе: «$name.o», «lib$name.*» и «$name».

Если в @names включены каталоги, они просматриваются перед @dl_library_path. Каталоги могут быть указаны как -Ldir. Все другие имена обрабатываются как имена файлов, которые нужно искать.

Рекомендуется использовать аргументы в форме -Ldir и -lname.

Пример:

@dl_resolve_using = dl_findfile(qw(-L/usr/5lib -lposix));
dl_expandspec()

Синтаксис:

$filepath = dl_expandspec($spec)

Некоторые необычные системы, такие как VMS, требуют специальной обработки имён файлов для обработки символических имён файлов (т. е. логических имён VMS).

Для поддержки этих систем функция dl_expandspec() может быть реализована либо в файле dl_*.xs, либо код может быть добавлен в функцию dl_expandspec() в DynaLoader.pm. См. DynaLoader_pm.PL для получения дополнительной информации.

dl_load_file()

Синтаксис:

$libref = dl_load_file($filename, $flags)

Динамически загрузить $filename, который должен быть путём к общему объекту или библиотеке. Возвращается неявный «ссылка на библиотеку» в качестве обработчика загруженного объекта. Возвращает undef при ошибке.

Аргумент $flags изменяет поведение dl_load_file. Назначенные биты:

0x01  make symbols available for linking later dl_load_file's.
      (only known to work on Solaris 2 using dlopen(RTLD_GLOBAL))
      (ignored under VMS; this is a normal part of image linking)

(На системах, которые предоставляют обработчик для загруженного объекта, таких как SunOS и HPUX, $libref будет этим обработчиком. На других системах $libref обычно будет $filename или указатель на буфер, содержащий $filename. Приложение не должно исследовать или изменять $libref каким-либо образом.)

Это функция, которая выполняет фактическую работу. Она должна использовать текущие значения @dl_require_symbols и @dl_resolve_using, если это необходимо.

SunOS: dlopen($filename)
HP-UX: shl_load($filename)
Linux: dld_create_reference(@dl_require_symbols); dld_link($filename)
VMS:   lib$find_image_symbol($filename,$dl_require_symbols[0])

(Функция dlopen() также используется Solaris и некоторыми версиями Linux, и является распространённым выбором при предоставлении «обёртки» над другими механизмами, как это делается в порте OS/2.)

dl_unload_file()

Синтаксис:

$status = dl_unload_file($libref)

Динамически разгрузить $libref, который должен быть неявной «ссылкой на библиотеку», возвращённой dl_load_file. Возвращает 1 при успехе и 0 при неудаче. Эта функция необязательна и может не предоставляться на всех платформах.

Если она определена и Perl скомпилирован с определённым C-макросом DL_UNLOAD_ALL_AT_EXIT, она вызывается автоматически при завершении интерпретатора для каждого общего объекта или библиотеки, загруженной DynaLoader::bootstrap. Все такие ссылки на библиотеки хранятся в @dl_librefs DynaLoader::Bootstrap при загрузке библиотек. Файлы разгружаются в порядке LIFO.

Эта разгрузка обычно необходима при встраивании перловской общей библиотеки (например, сконфигурированной с помощью -Duseshrplib) в более крупное приложение, и перловский интерпретатор создаётся и уничтожается несколько раз в течение срока службы приложения. В этом случае возможно, что системный динамический компоновщик разгрузит, а затем повторно загрузит общую библиотеку libperl, не перераспределяя никакие ссылки на неё из каких-либо файлов, DynaLoaded предыдущей инстанцией интерпретатора. В результате любые общие объекты, открытые DynaLoader, могут указывать на теперь недействительный «призрак» общей библиотеки libperl, что приведёт к очевидно случайному повреждению памяти и сбоям. Это поведение чаще всего наблюдается при использовании Apache и mod_perl, построенных с механизмом APXS.

SunOS: dlclose($libref)
HP-UX: ???
Linux: ???
VMS:   ???

(Функция dlclose() также используется Solaris и некоторыми версиями Linux, и является распространённым выбором при предоставлении «обёртки» над другими механизмами, как это делается в порте OS/2.)

dl_load_flags()

Синтаксис:

$flags = dl_load_flags $modulename;

Предназначен для вызова метода и для переопределения производным классом (т. е. классом, у которого DynaLoader в @ISA). Определение в DynaLoader само по себе возвращает 0, что обеспечивает стандартное поведение от dl_load_file().

dl_find_symbol()

Синтаксис:

$symref = dl_find_symbol($libref, $symbol)

Возвращает адрес символа $symbol или undef если не найден. Если целевая система имеет отдельные функции для поиска символов разных типов, dl_find_symbol() должен сначала искать символы функций, а затем другие типы.

Точный способ возвращения адреса в $symref в настоящее время не определён. Единственное начальное требование заключается в том, что $symref может быть передан и понят dl_install_xsub().

SunOS: dlsym($libref, $symbol)
HP-UX: shl_findsym($libref, $symbol)
Linux: dld_get_func($symbol) and/or dld_get_symbol($symbol)
VMS:   lib$find_image_symbol($libref,$symbol)
dl_find_symbol_anywhere()

Синтаксис:

$symref = dl_find_symbol_anywhere($symbol)

Применяет dl_find_symbol() к элементам @dl_librefs и возвращает первую найденную совпадение.

dl_undef_symbols()

Пример

@symbols = dl_undef_symbols()

Возвращает список имён символов, которые остаются неопределёнными после load_file(). Возвращает () если неизвестно. Не беспокойтесь, если ваша платформа не предоставляет механизм для этого. Большинство не нуждаются в нём и, следовательно, не предоставляют его, а просто возвращают пустой список.

dl_install_xsub()

Синтаксис:

dl_install_xsub($perl_name, $symref [, $filename])

Создаёт новую внешнюю подпрограмму Perl с именем $perl_name, используя $symref в качестве указателя на функцию, которая реализует подпрограмму. Это просто прямой вызов newXS()/newXS_flags(). Возвращает ссылку на установленную функцию.

Параметр $filename используется Perl для идентификации исходного файла для функции, если это требуется die(), caller() или отладчиком. Если $filename не определён, будет использоваться «DynaLoader».

bootstrap()

Синтаксис:

bootstrap($module [...])

Это стандартная точка входа для автоматической динамической загрузки в Perl.

Она выполняет следующие действия:

  • находит каталог auto/$module, перебирая @INC

  • использует dl_findfile() для определения имени файла для загрузки

  • устанавливает @dl_require_symbols в ("boot_$module")

  • выполняет файл auto/$module/$module.bs, если он существует (обычно используется для добавления в @dl_resolve_using любых файлов, необходимых для загрузки модуля в текущей платформе)

  • вызывает dl_load_flags() для определения способа загрузки файла.

  • вызывает dl_load_file() для загрузки файла

  • вызывает dl_undef_symbols() и выводит предупреждение, если какие-либо символы не определены

  • вызывает dl_find_symbol() для "boot_$module"

  • вызывает dl_install_xsub() для его установки как "${module}::bootstrap"

  • вызывает &{"${module}::bootstrap"} для загрузки модуля (на самом деле используется ссылка на функцию, возвращаемую dl_install_xsub, для повышения скорости)

Все аргументы bootstrap() передаются в функцию загрузки модуля. Код по умолчанию, сгенерированный xsubpp, ожидает $module [, $version]. Если необязательный аргумент $version не указан, он по умолчанию равен $XS_VERSION // $VERSION в таблице символов модуля. Код по умолчанию сравнивает версию в пространстве Perl с версией скомпилированного кода XS и выдаёт ошибку, если они не совпадают.

АВТОР

Тим Бэнс, 11 августа 1994 года.

Этот интерфейс основан на работе и комментариях (в произвольном порядке): Ларри Уолл, Роберт Сандерс, Дийн Роэрих, Джефф Окамото, Анно Зигель, Томас Нейман, Пол Маркесс, Чарльз Бейли, я и другие.

Ларри Уолл разработал элегантный механизм наследования загрузки и реализовал первый динамический загрузчик Perl 5, используя его.

Глобальная загрузка для Solaris добавлена Ником Ингом-Симмонсом с помощью помощи в разработке/кодировании от Тима Бэнса, январь 1996 года.

© 1993–2023 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.38.0/DynaLoader

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API