Главная » Delphi » Статическая компановка против динамической

0

Статической  компоновкой (static  linking) называется метод,  с помощью которого компилятор Delphi  реализует в исполняемом коде  вызов  функций  и процедур. Код функций  может  храниться в файле приложения с расширением .dpr или  в любом другом модуле, но при компоновке приложений эти функции и процедуры становятся частью  исполняемого файла. Другими  словами, каждая  функция  будет  занимать на диске определенное место в составе исполняемого файла  (.exe) программы.

Расположение функции заранее определено относительно места,  занимаемого в

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

Это  весьма  упрощенное описание действительно сложного процесса, используе мого компилятором Delphi для статической компоновки. Но эта книга не о тонкостях работы компилятора и не о внутренней структуре  выполнения программ. Для эффек тивного использования DLL в приложении такие подробности не так уж и важны.

НА ЗАМЕТКУ

В Delphi реализован интеллектуальный компоновщик (smart linker), автоматически удаляющий функции, процедуры, переменные и типизированные константы, на кото- рые нет ссылок в окончательном варианте проекта. Следовательно, расположенные в больших модулях функции, не используемые в данном проекте, никогда не становятся частью создаваемого исполняемого файла.

Предположим, существуют  два  приложения,  которые  используют одну  и  ту же функцию, находящуюся в некотором модуле. В обоих  приложениях имя  данного мо дуля, безусловно, будет указано в разделе uses. Если одновременно запустить оба приложения в среде  Windows,  то код этой  функции будет загружен  в память  дважды. В случае  запуска  третьего приложения в памяти появится и третий экземпляр этой функции, общий  расход  памяти также  будет втрое большим. Приведенный выше при мер  иллюстрирует одну из главных  причин использования динамической компонов ки. Если такую функцию расположить в библиотеке DLL, то при  ее загрузке  в память одним приложением все остальные приложения, которым потребуется ссылка на нее, смогут использовать ее код с помощью отображения образа данной библиотеки DLL на адресное пространство их собственных процессов. В результате, данная  функция будет существовать в памяти только  в одном экземпляре — теоретически.

При  динамической компоновке (dynamic linking) связь  между вызовом функции и ис полняемым кодом  устанавливается во  время  его  выполнения с  помощью внешней ссылки  на конкретную функцию библиотеки DLL. Подобные ссылки  могут быть  объ явлены в самом  приложении, но обычно они  размещаются в отдельном модуле im- port. В этом модуле объявляются импортируемые функции и процедуры, а также  оп ределяются различные типы данных, используемые функциями библиотек DLL.

Предположим, например, что  библиотека DLL по  имени MaxLib.dll содержит следующую функцию:function Max(I1, I2: integer): integer;

Эта функция возвращает большее  из двух переданных ей целых  чисел.  Типичный модуль import для данной функции будет выглядеть таким образом:

unit MaxUnit;

interface

function Max(I1, I2: integer): integer;

implementation

function Max; external ‘MAXLIB';

end.

Можно  заметить, что,  хотя  эта функция внешне  напоминает типичный модуль, в ней нет определения функции Max(). Ключевое слово external просто указывает на то,  что  данная  функция находится в файле, имя  которого приведено сразу  за этим ключевым словом.  Для  использования  указанного модуля  приложению достаточно иметь  в списке  раздела  uses его  имя,  т.е.  MaxUnit. При  выполнении приложения библиотека DLL загружается в память  автоматически, и любые  обращения к функции Max() связываются с функцией Max(), находящейся в этой библиотеке.

Этот пример иллюстрирует один из двух способов загрузки библиотек DLL, назы

ваемый  неявной загрузкой (implicit loading). Он  требует  от Windows  автоматически за гружать  библиотеку DLL при  загрузке  приложения. Второй способ  называется явной загрузкой (explicitly  load)  DLL и будет рассматриваться в настоящей главе далее.

Зачем нужны библиотеки DLL?

Существует  несколько причин использования библиотек DLL,  часть  из  которых уже упоминалась выше. Как правило, такие  библиотеки применяются либо для совме стного  использования кода и системных ресурсов, либо для сокрытия реализации программного кода или системных функций низкого уровня,  либо для реализации пользовательских элементов управления. Эти  темы  и  рассматриваются в последую щих разделах.

Источник: Тейксейра, Стив, Пачеко, Ксавье.   Borland Delphi 6. Руководство разработчика. : Пер.  с англ. — М. : Издательский дом “Вильямс”, 2002. —  1120 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии