Читаем Linux API. Исчерпывающее руководство полностью

Если разделяемая библиотека, указанная с помощью аргумента libfilename, зависит от других библиотек, то dlopen() загрузит их автоматически. При необходимости эта процедура выполняется рекурсивно. Мы будем называть набор загруженных таким образом библиотек деревом зависимостей.

Функцию dlopen() можно вызвать несколько раз для одной и той же библиотеки. При этом загрузка будет выполнена лишь при первом вызове, а во всех последующих случаях станет возвращаться одно и то же значение handle. Однако программный интерфейс dlopen хранит счетчик ссылок для каждого дескриптора. С каждым вызовом dlopen() он инкрементируется, а декрементация происходит при вызове dlclose(); последний выгружает библиотеку из памяти только в том случае, если счетчик равен 0.

Аргумент flags представляет собой битовую маску, значение которой должно быть равно либо RTLD_LAZY, либо RTLD_NOW. Эти константы описаны ниже.

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

• RTLD_NOW — все неопределенные ссылки библиотеки должны быть немедленно разрешены вне зависимости от того, понадобятся ли они когда-нибудь; данные операции нужно произвести до завершения вызова dlopen(). Это замедляет загрузку библиотеки, но позволяет сразу же определить все ошибки, связанные со ссылками на функции. Такой подход может оказаться полезным при отладке приложения или в случае, когда при обнаружении неразрешенного символа программа должна завершиться немедленно, а не в ходе дальнейшего выполнения.

Присвоив переменной среды LD_BIND_NOW любое значение, кроме пустой строки, мы можем заставить динамический компоновщик немедленно выполнить поиск всех символов (то есть как и в случае с RTLD_NOW) при загрузке разделяемой библиотеки, указанной в списке динамических зависимостей исполняемого файла. Эта переменная поддерживается в glibc 2.1.1 и выше. Ее установка нивелирует действие флага RTLD_LAZY при вызове dlopen().

В маску flags также можно включить дополнительные значения, описанные в стандарте SUSv3:

• RTLD_GLOBAL — символы в текущей библиотеке и ее дереве зависимостей можно задействовать для разрешения ссылок в других библиотеках, загруженных тем же процессом, а также для поиска с помощью вызова dlsym();

• RTLD_LOCAL — это значение используется по умолчанию (если не указаны другие константы) и имеет эффект, противоположный RTLD_GLOBAL. Оно делает так, что символы в текущей библиотеке и ее дереве зависимостей становятся недоступными для разрешения ссылок в загружаемых библиотеках.

В стандарте SUSv3 не уточняется, какое значение используется по умолчанию, если ни одна из констант (RTLD_GLOBAL или RTLD_LOCAL) не указана явно. В большинстве реализаций UNIX, как и в Linux, по умолчанию устанавливается флаг RTLD_LOCAL, но есть и такие, в которых вместо этого задействован RTLD_GLOBAL.

Linux также поддерживает несколько нестандартных флагов.

• RTLD_NODELETE (начиная с glibc 2.2) — предотвращает выгрузку библиотеки при вызове dlclose(), даже если счетчик ссылок равен 0. Это значит, что статические переменные библиотеки не будут заново инициализированы при следующем вызове dlopen() (для библиотек, загружаемых автоматически динамическим компоновщиком, подобного эффекта можно достичь, используя параметр gcc — Wl, — znodelete на этапе их создания).

• RTLD_NOLOAD (начиная с glibc 2.2) — не дает загрузить библиотеку. Такое поведение имеет две цели. Во-первых, с помощью этого флага можно проверить, загружена ли заданная библиотека в адресное пространство процесса. В случае положительного ответа dlopen() возвращает ее дескриптор; в противном случае возвращается NULL. Во-вторых, данный флаг позволяет применить аргумент flags уже загруженной библиотеки. Например, можно указать в маске flags значение RTLD_NOLOAD | RTLD_GLOBAL при вызове dlopen() для библиотеки, открытой ранее с флагом RTLD_LOCAL.

• RTLD_DEEPBIND (начиная с glibc 2.3.4) — при разрешении символьных ссылок, созданных текущей библиотекой, поиск определений выполняется сначала в данной библиотеке и только потом в библиотеках, загруженных ранее. Это позволяет сделать библиотеку самодостаточной и отдавать приоритет собственным символам перед глобальными, если нужное имя встречается в уже загруженных библиотеках (похоже на то, как действует параметр компоновщика — Bsymbolic, описанный в разделе 41.12).

Флаги RTLD_NODELETE и RTLD_NOLOAD также реализованы в программном интерфейсе dlopen нескольких других операционных систем, включая Solaris. Флаг RTLD_DEEPBIND поддерживается только в Linux.

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных