Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

На главную -> MyLDP -> Программирование и алгоритмические языки


Ulrich Drepper "Как писать разделяемые библиотеки"
Назад Оглавление Вперед

3. Сопровождение интерфейсов API и ABI

Когда пишутся объекты DSO, используемые во многих проектах в виде ресурсов, освоение технических аспектов написания оптимизированных разделяемых объектов DSO является всего лишь частью того, что необходимо. В успешном проекте более важную роль играют сопровождение интерфейса программирования (API) и интерфейса двоичных модулей (ABI). Без API и ABI стабильная работа DSO ляжет большим бременем или будет невозможна. В этом разделе мы представим ряд правил, которые повышают шансы на успех проектов, в которых предоставляются интерфейсы для их использования в других проектах. Мы расскажем конкретно о библиотечной реализации объектов DSO, но большинство правил можно распространить на проекты любого вида.

3.1. Что такое интерфейсы API и ABI?

Объекты DSO используются как во время компиляции, так и во время выполнения. Во время компиляции компоновщик пытается из определений, имеющихся в DSO, разрешить неопределенные ссылки. Затем компоновщик связывает ссылку с определением в объекте DSO. В объектах ELF эта ссылка явно не присутсвует, поскольку с помощью поиска символов можно найти различные определения во время выполнения приложения. Однако будет отмечено, что ссылка уже разрешена. Во время выполнения программы можно рассчитывать на то, что определение будет присутствовать. Этого может не случиться, если в между временем, когда осуществлялась компоновка, и временем, когда исполняется программа, что-то произойдет в объекте DSO. Изменение, в результате которого символ исчезает, как правило, является фатальным. В некоторых случаях можно использовать определения из других DSO, но на это, как правило, не следует рассчитывать. Символ, который однажды был экспортирован, должен в будущем быть доступным во время выполнения приложения.

В состав интерфейса ABI из DSO обычно входит коллекция всех определений, которые доступны для использования во время жизни DSO. Поддержка совместимости ABI означает, что определение, которое также называется интерфейсом, не должны пропадать. Хотя это всего лишь самая простая часть.

Для определений переменных это также означает, что размер и структура переменной не должна изменяться так, чтобы приложение не смогло обработать переменную. В действительности это означает, что все зависит от ситуации. Если какой-либо код, находящийся вне объекта DSO, напрямую обращается к переменной, то часть структуры, через которую происходит обращение к переменной, изменяться не должна. На платформах, на которых для обработки обращений к переменным, находящимся в DSO, необходимы перемещения копий в главное приложение (например, на IA-32), размер переменной вообще не должен изменяться. В противном случае размер переменных может увеличиться.

Требования к определениям функций проверять еще сложнее. Задокументированная семантика функции изменяться не должна. Однако, определить "семантику" для любой нетривиальной функции достаточно сложно. В следующем разделе мы попытаемся определить требования к стабильному интерфейсу. Стабильность, в своей основе означает, что корректные программы, которые работали в прошлом, должны продолжать работать и в будущем. Поэтому одно из требований состоит в том, не должны изменяться параметры функции. Это приводит нас к интересному факту: в языке C++ это обеспечивается автоматически. В трансформированных именах функций указываются типы параметров функции. Это означает, что любое изменение в сигнатуре функции приведет к ошибкам времени компиляции и времени выполнения и, следовательно, это легко обнаружить. Это не относится к переменным; в их трансформированных именах указывается только часть пространства имен. Это еще одна хорошая причина, чтобы не экспортировать переменные, как часть API.


Предыдущий раздел:   Следующий раздел:
Назад Оглавление Вперед