Вход/Регистрация
Разработка приложений в среде Linux. Второе издание
вернуться

Троан Эрик В.

Шрифт:

const char * dlerror(void);

Каждый раз при возврате значения она очищает состояние ошибки. Если не будет создано другое состояние ошибки, она продолжит выполнение, чтобы вернуть

NULL
вместо строки. Объяснение этого необычного поведения можно найти в описании функции
dlsym
.

Функция

dlopen
открывает библиотеку. Этот процесс включает поиск библиотечного файла, открытие файла и выполнение некоторой предварительной обработки. Переменные окружения и параметры, переданные функции
dlopen
, определяют детали этого процесса.

void * dlopen(const char * filename, int flag);

Если

filename
является абсолютным путем (то есть начинается с символа
/
), то функции
dlopen
не нужно производить поиск библиотеки. Это обычный способ применения функции
dlopen
в коде приложения. Если
filename
является простым именем файла, то функция
dlopen
произведет поиск библиотеки
filename
в перечисленных ниже местах.

• Набор каталогов, разделенных двоеточием, который определен в переменной окружения

LD_ELF_LIBRARY_PATH
, или, если ее не существует, в переменной
LD_LIBRARY_PATH
.

• Библиотеки, определенные в файле

/etc/ld.so.cache
. Этот файл генерируется программой
ldcoding
, регистрирующей каждую библиотеку, которую она находит в каталоге, указанном в
/etc/ld.so.conf
, во время ее выполнения.

• 

/usr/lib

• 

/lib

Если filename равен

NULL
, то функция
dlopen
открывает экземпляр текущего исполняемого файла. Это полезно только в редких случаях. В случае сбоя функция
dlopen
возвращает
NULL
.

Поиск файлов является простой частью работы функции

dlopen
; разрешение символов является более сложной задачей. Существует два фундаментально разных типа разрешения символов: немедленный (immediate) и отложенный (lazy). При немедленном разрешении функция
dlopen
разрешает все неразрешенные символы до возвращения результата; под отложенным разрешением подразумевается, что разрешение символов будет происходить по требованию.

Если большинство символов будет разрешено в самом конце, то гораздо эффективнее будет выполнить немедленное разрешение. Однако для библиотек со многими неразрешенными символами время, потраченное на разрешение символов, может оказаться продолжительным; если это существенно сказывается на вашем пользовательском интерфейсе, можно отдать предпочтение отложенному разрешению. Разница в общей эффективности будет незначительной.

Во время разработки и отладки вы практически во всех случаях будете использовать немедленное разрешение. Если ваши разделяемые объекты имеют неразрешенные символы, вам нужно будет знать об этом немедленно, а не тогда, когда в программе произойдет сбой во время выполнения кода, который на первый взгляд не будет иметь к этому отношения. Отложенное разрешение станет причиной сложно воспроизводимых ошибок, если вы не проверите свои разделяемые объекты сначала с немедленным разрешением.

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

b
в разделяемом объекте В, а В загружается после А, то отложенное разрешение
b
сможет быть выполнено только после загрузки объекта В, а до его загрузки — нет. Если написать код с немедленным разрешением, то вы сможете перехватить эту ошибку еще до того, как она сможет стать причиной возникновения проблем.

Здесь подразумевается, что загружать модули нужно всегда в обратном порядке по отношению к их зависимостям: если объект А зависит от объекта В в некоторых его символах, вы должны загрузить объект В до загрузки объекта А, и должны выгрузить объект А до выгрузки объекта B. К счастью, многие приложения с динамически загружаемыми разделяемыми объектами не имеют подобных взаимозависимостей.

По умолчанию символы в разделяемом объекте не экспортируются и потому не используются для разрешения символов в остальных разделяемых объектах. Они будут доступны только для их поиска и использования, о чем будет сказано в следующем разделе. Однако вы можете экспортировать все символы из одного разделяемого объекта во все остальные разделяемые объекты; эти символы будут доступны всем разделяемым объектам, которые будут загружены позже.

Управление всеми этими действиями осуществляется через аргумент

flags
. Он должен иметь значение
RTLD_LAZY
для отложенного разрешения и
RTLD_NOW
для немедленного разрешения. Любое из этих значений может быть объединено битовым "ИЛИ" с
RTLD_GLOBAL
, чтобы разрешить экспортирование символов в остальные модули.

Если разделяемый объект экспортирует программу

_init
, то она будет выполняться до того, как функция
dlopen
вернет результат.

Функция

dlopen
возвращает дескриптор (handle) того разделяемого объекта, который она открыла. Это непрозрачный объектный дескриптор, который следует использовать только как аргумент для последующих вызовов функций
dlsym
и
dlclose
. Если разделяемый объект открывается несколько раз, функция
dlopen
каждый раз будет возвращать один и тот же дескриптор, и с каждым новым вызовом счетчик ссылок будет увеличиваться на единицу.

  • Читать дальше
  • 1
  • ...
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: