Читаем 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.

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

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

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных
1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

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

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

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

В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки. Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию

Герберт Шилдт

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