Динамические библиотеки

В Windows и OS/2 используется именно такой способ загрузки. Исполняе­мый модуль в этих системах содержит ссылки на другие модули, называе­мые DLL (Dynamically Loadable Library, динамически загружаемая библиоте­ка). Фактически, каждый модуль в этих системах обязан содержать хотя бы одну ссылку на DLL, потому что интерфейс к системным вызовам в этих ОС также реализован в виде DLL.

DLL представляют собой библиотеки в том смысле, что обычно они соби­раются из нескольких объектных модулей. Но, в отличие от архивных биб­лиотек, из DLL нельзя извлечь отдельный модуль, при присоединении биб­лиотеки к программе она присоединяется и загружается целиком.

Главное достоинство DLL состоит в том, что модуль (как основной, так и библиотечный), по собственному желанию, может выбирать различные биб­лиотеки, подгружая их уже после своей собственной загрузки. При этом нет даже строгого ограничения на совместимость этих библиотек по вызовам (две библиотеки совместимы по вызовам, если они имеют одинаковые точки входа с одинаковой семантикой): загрузчик предоставляет возможность просмотреть список глобальных символов, определенных в библиотеке и получить указатель на каждый символ, обратившись к нему по имени; (впрочем, количество и типы параметров или тип переменной, а тем более их семантику, загрузчик не сообщает - эту информацию надо получать из других источников, например из списка зарегистрированных в системе объектов СОМ).

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

Другая проблема, обусловленная широким использованием разделяемого кода, состоит в слежении за версией этого кода.